При любом вводе, если M <= N, все работает нормально.
Идея простая - во втором обходе идем с конца и вписываем на место st[ N - 1 - i ] (это i-й элемент с конца) элемент st[ M - 1 - i ] (нулевой с конца, то есть последний в списке, получает значение (M-1)-го, и т.д.
package com.javarush.task.task07.task0720;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
/*
Перестановочка подоспела
*/
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
//напишите тут ваш код
int N = Integer.parseInt(reader.readLine());
int M = Integer.parseInt(reader.readLine());
ArrayList<String> st = new ArrayList<String>(N);
for (int i = 0; i < N; i++){
st.add(reader.readLine());
}
//идем от последнего элемента и добавляем (M-1)-й элемент вместо последнего, (M - 2)-й вместо предпоследнего и т.д.,
for (int i = 0; i < M; i++){
st.set(N - 1 - i, st.get(M - 1 - i));
}
for (int i = 0; i < N; i++){
System.out.println(st.get(i));
}
}
}
/* ввод
4
3
aa
bb
cc
dd
вывод:
aa
aa
bb
cc
*/