Search code examples
javaarraysalgorithmrotationarray-algorithms

How to swap the sub-arrays?


How to rearrange a subarray of integers (for a random m) without auxiliary array like this?

example input [1,2,3,4,5,6,7,8,9,10]            
m=3;             
expected output :
[4,5,6,7,8,9,10,1,2,3]

example input : 
[1,2,3,4,5]            
m=4
example output         
[5,1,2,3,4]   
                 
example input :
[1,2,3,4,5,6]        
m=2              
example output
[3,4,5,6,1,2]  
    

I have tried creating a temp array and it worked but can it be done more memory efficient.


Solution

  • Yes, you can solve this in O(n) time and O(1) space. This involves reversing subarrays.

    Let's take below one as an example:

    [1,2,3,4,5,6,7,8,9,10]

    m = 3

    • Have 2 pointers and swap the first and last element, second with second last and so on. So, with the above example, our array would look like:

      [10,  9,  8,  4,  5,  6,  7,  3,  2,  1]
       ----------                   ---------
            A                           C
                    -------------
                          B
      
    • Important: If value of m is greater than half of the size of the array, you would stop the swapping there itself.

    • In the above scenario, we have successfully divided the array into 3 parts which I have named as A,B and C.

    • Now, reverse part C. So this part is now figured out.

      [10,  9,  8,  4,  5,  6,  7,  1,  2,  3]
       ----------                   
            A                           
                    -------------
                          B
      
    • Reverse part B which would look like below

      [10,  9,  8,  7,  6,  5,  4,  1,  2,  3]
       ----------                   
            A                           
                    -------------
                          B
      
    • Now, reverse the entire part (B + A) which is your final output.

      [4,  5,  6,  7,  8,  9,  10,  1,  2,  3]
      

    Note: Sometimes, it's possible that part B won't exist. So you would just reverse the entire A array in this case(or you can add additional if conditions)

    Snippet:

         private static void rotateArray(int[] arr,int m){
            int left = 0,right = arr.length - 1;
            int limit = Math.min(m,arr.length/2);
            while(left < limit){
                swap(arr,left++,right--);
            }
    
            reverse(arr,arr.length - m,arr.length-1);
            reverse(arr,m,arr.length-m-1);
            reverse(arr,0,arr.length-m-1);
        }
    
        private static void reverse(int[] arr,int left,int right){
            while(left < right){
               swap(arr,left++,right--);
            }
        }
    
        private static void swap(int[] arr,int x,int y){
            int temp = arr[x];
            arr[x] = arr[y];
            arr[y] = temp;
        }
    

    Demo: https://onlinegdb.com/HklMoZKG4U