I need to left circular rotate an arraylist based on each element of a second arraylist and then return another list that has the max element index of the rotated arraylist. (each rotation should be performed on the original arraylist formation)
For example i have this two arraylist : rotatelist[1,2,3,4] , rotate[1,2,3]
The flow would be:
rotatelist[1,2,3,4],rotate[1] -> [2,3,4,1] : max element index= 2
rotatelist[1,2,3,4],rotate[2] -> [3,4,1,2] : max element index= 1
rotatelist[1,2,3,4],rotate[3] -> [4,3,2,1] : max element index= 0
The code below works fine, but when a test case, which has both arraylist element size reach about 100,000 a "Terminated due to timeout" error always shows, because I'm running this on HackerRank
List<Integer> indices = new ArrayList<>(rotate.size());
for(int i=0;i<rotate.size();i++){
//rotate arraylist to the left
Collections.rotate(rotatelist,-rotate.get(i));
//get and insert max element index to array
indices.add(rotatelist.indexOf(Collections.max(rotatelist)));
//rotate back to previous positions
Collections.rotate(rotatelist,rotate.get(i));
}
return indices;
So is there another way to optimize the performance of this code?
Is using a traditional for loop better than using Collections.rotate() performance wise?
Firstly, forget about actually rotating anything, and instead think about what happens to just one of the elements in particular - the largest one.
I don’t want to spoon feed you code. Instead, consider these ideas:
Find the largest element’s index, call it iMax
.
The position of the largest element after rotating n
is (iMax - n + array.length) % array.length
.
If n
can be less than zero or greater than array.length
, you will need to bring it within that range by using the fact that for positive n, rotations of n
and n % array.length
give the same result.
You should be able to build some code around these ideas.