DEV Community

Prashant Mishra
Prashant Mishra

Posted on

Maximum swap

Problem

TC: O(n)O(n)
SC: O(n)O(n)

class Solution {
    public int maximumSwap(int num) {
        // list to keep track of digits in num
        List<Integer> list = new ArrayList<>();
        int no = num;// store num in no variable

        //put all the digits  of nums in list
        while(num!=0){
            list.add(0,num%10);
            num = num/10;
        }

        // push all the digits in decresing order in stack
        //why ? since we will get the max no. by swapping leftmost value that is smaller than the max value from the rightmost side e.g 98368 will be come 98863, that is left most swapalbe smallest value 3 is swapped with right most largest value that is 8
        // with stack we will have values from smallest (at top ) to least smallest at the bottom
        //hence when a rightmost maximum value can be swapped with the stack top value then, we will keep poping the stack as there is a chance that the next smaller value might also be smaller than the rightmost value from the right.
        //finally when it is not possile to further swap break out from the loop and swap the most recent indexes tracked
        Stack<Integer> s1 = new Stack<>();
        s1.push(0);//1st element will the largest 

        //...then we will push smaller indexes of values in the stack compared to stack top
        int index = 1;
        while(index<list.size() && list.get(index)<=list.get(s1.peek())){
             s1.push(index++);
        }


        int rightIndex = -1;//intialize
        //get the the rightmost index of the maximum value/digit between 'index' to 'list.size()-1'
        //this is because till `index-1`  is already  been covered in finding the smallest values indexes in decresing order while populating the stack
        for(int i = list.size()-1;i>=index;i--){ //from last index to towards left till `index`
            if(rightIndex ==-1 || list.get(rightIndex) < list.get(i)) rightIndex = i;
        }
        if(rightIndex ==-1) return no;// if not right most index is found between window index and list.size()-1 then retun the num as the digits are in descending order and no. max value can be created in digits in descending order

        int i = s1.peek(), j = rightIndex;
        //finally keep finding the left most index that has value smaller than the rightmostindex value
        while(!s1.isEmpty()){
            if(list.get(s1.peek()) < list.get(rightIndex)){
                i = s1.peek();
                j = rightIndex;
                s1.pop();
            }
            else break;// if not possible anymore then break out
        }

        // swap the indexes
        int temp   =  list.get(i);
        list.set(i,list.get(j));
        list.set(j,temp);

        // regenerate the value from the new digits
        num = list.get(0);
        index = 1;
        while(index<list.size()){
            num =num*10 + list.get(index);
            index++;
        }
        //finally return the value
        return num;
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)