Executando verificação de segurança...
1

Se eu entendi direito, dá para fazer de forma mais simples:

String str = "TANTOFAZOTEXTO";
int quebraLinhas = 3; // dividir a string em 3 partes iguais
int qtdChar = str.length() / quebraLinhas; // tamanho de cada parte
String[] partes = new String[quebraLinhas]; // array com as partes
String sobra = "";
for (int i = 0; i < str.length(); i += qtdChar) {
    if (i + qtdChar <= str.length()) { // ainda tem caracteres suficientes para ser uma parte
        int indice = i / qtdChar;
        String parte = str.substring(i, i + qtdChar);
        if (indice % 2 == 0) { // índice par, inverte a string
            partes[indice] = new StringBuilder(parte).reverse().toString();
        } else {
            partes[indice] = parte;
        }
    } else { // último pedaço é a sobra
        sobra = str.substring(i);
    }
}

// em vez de concatenar strings, use um StringBuilder para ir montando a string aos poucos
StringBuilder sb = new StringBuilder();
// i é o índice do array de partes, j é o índice da sobra
for (int i = 0, j = 0; i < partes.length; i++) {
    if (i % 2 == 0 && j < sobra.length()) { // índice par e ainda tem caracteres da sobra para usar
        if (j % 2 == 0) { // insere a sobra antes
            sb.append(sobra.charAt(j));
            sb.append(partes[i]);
        } else { // insere a sobra depois
            sb.append(partes[i]);
            sb.append(sobra.charAt(j));
        }
        j++;
    } else { // índice ímpar, ou não tem mais caracteres da sobra
        sb.append(partes[i]);
    }
}
sb.append(sobra); // adicione a sobra também

System.out.println(sb.toString()); // TTNATOFAZXETOOTO
Carregando publicação patrocinada...
1

Só tem um problema nessa lógica, se alterada a quantidade quebras de linhas, a sobra do índice "par", ficaria no meio da String. Nesse caso, a primeira iteração da sobra "par" fica no índice 2. A variável quebraLinhas sendo 4, seria um problema.

O seu código ficou muito mais show, kkkkk.

Mas fiz as alterações para que fique sempre no final as sobras "pares".

Vê se está correto o código. Ele rodou perfeitamente, mas se está correto no sentido de é a melhor forma.

public static void main(String[] args) {

	String str = "TANTOFAZOTEXTO";
	int quebraLinhas = 4;
	int qtdChar = str.length() / quebraLinhas;
	//int resto = str.length() % quebraLinhas;
	String[] partes = new String[quebraLinhas];
	//int contador = 0;
	String sobra = "";

	//Esse for roda até percorrer toda a String
	//a var "i" incrementa de acordo com a quantidade de caracteres em cada quebra de linha
	for (int i = 0; i < str.length(); i+=qtdChar) {
		if (i + qtdChar <= str.length()) { //Esse if valida se o índice inicial até o final é menor que a quantidade de caracteres que ainda tem
			String parte = str.substring(i, i + qtdChar); //Esse método copia o "pedaço" da String que queremos
			int indice = i / qtdChar; //Essa divisão vai sempre dar o indice na sequencia que precisamos: 0, 1 ,2 ....
			if ( indice % 2 == 0) { //Verifica se é par
				//Instanciamos o objeto parte novamente mas na classe StringBuilder ao invés de String, o método reverse reverteu o pedaço da String
				//e como ele não retorna nada, usamos toString para passar o valor.
				partes[indice] = new StringBuilder(parte).reverse().toString();
			} else {
				partes[indice] = parte;
			}
		} else {
			sobra = str.substring(i); //Passando apenas um índice, esse método pega do índice informado até o fim
									  //sem precisar iterar para conseguir todos ou usar uma lógica para passar o
									  //argumento correto para uma substring com os índices iniciais e finais
		}
		
		
	}
	
	//ao invés de concatenar a String, usar o StringBuilder para construir aos poucos
	//StringBuilder é mais performático
	StringBuilder sb = new StringBuilder();
	StringBuilder sbSobra = new StringBuilder();
	
	for (int i = 0, j = 0; i < partes.length; i++) {
		if (i % 2 == 0 && j < sobra.length()) { //Se o índice for par e ainda houver sobra suficiente
			if (j % 2 == 0) { //Começando com 0 que é par, insere antes, e no próximo que é impar, insere depois e sucessivamente
				sb.append(sobra.charAt(j));
				sb.append(partes[i]);
			} else {
				sb.append(partes[i]);
				sbSobra.append(sobra.charAt(j));
			}
			j++;
		} else { //índice ímpar, acrescenta a sobra depois
			sb.append(partes[i]);
		}
	}
	sb.append(sbSobra);
	System.out.println(sb.toString());

}
    

Esses comentários "óbvios" que coloquei é para eu perder menos tempo tentando ler o código quando quiser revisar alguma coisa. Visto que eu salvo todos os pacotes que crio pra poder consultar depois.