Algorithm problem: dictionary order algorithm

Keywords: Java

I want to sort out the algorithm problems I encounter every time.

Algorithm Title:

Given a positive integer, a method is implemented to find the number of transposed digits nearest to the integer and larger than itself.
To change the number of digits is to arrange all the digits of an integer to get a new number, such as 54321 and 23541

Train of thought:

1. To find a number close to a given number is to change the status of the number. That is, to find an area in reverse order

2. If the reverse region can no longer be transformed into a larger number, that is, on the way 54, the transformation will not be greater than it, so it is necessary to exchange the number closest to the reverse region with the number in the reverse region.
That is, if shown, the reverse order region of 12354 is the last two bits, only to see that these two bits are the current maximum combination. If you want to be closest to the original number and larger than the original number, you must start from the third from the bottom.
How to change? The third place from the bottom of 12345 is 3. We need to find the number just larger than 3 in the reverse order area, and exchange it with the position of 3:

3. Because you need to be close to the given number, the number in the reverse order area should be as small as possible after the end of step 2.
That is, change the reverse region to the order.
The temporary result after interchange is 12453. The last three bits have been determined. At this time, the last two bits are still in reverse order. We need to change the last two bits back to order to ensure that the last two bits are as small as possible when the value of the last three bits is 4:

In this way, we get the desired result 12435.

Step summary:

There are three steps to get the latest transposed digits:
1. Look at the reverse region from the back to the front, and find the first bit of the reverse region, that is, the boundary of digital replacement
2. Exchange the previous bit of the reverse region and the digit just larger than it in the reverse region
3. Change the original reverse order area to order

Algorithm implementation:

Several methods have realized the above steps.

import java.util.Arrays;

public class Test{
    public static int[] findNearestNumber(int[] numbers){
        //Copy the array to avoid direct operation from the original array
        int[] numbersCopy = Arrays.copyOf(numbers, numbers.length);
        //Find the subscript of the boundary value of the reverse region
        int index = findTransferPoint(numbersCopy);
        if(index == 0){
            return null;
        }
        //Exchange boundary value and the number greater than the boundary value in the reverse order region
        exchangeHead(numbersCopy,index);
        //Turn the reverse region into a sequence
        reverse(numbersCopy,index);

        return numbersCopy;
    }

    private static int findTransferPoint(int[] numbers){
        for(int i=numbers.length-1;i>0;i--){
            if(numbers[i] > numbers[i-1]){
                return i;
            }
        }
        return 0;
    }

    private static int[] exchangeHead(int[] numbers,int index){
        int head = numbers[index-1];
        for(int i = numbers.length-1;i > 0;i--){
            if(head <numbers[i]){
                numbers[index-1] = numbers[i];
                numbers[i] = head;
                break;
            }
        }
        return numbers;
    }
    //Because the reverse regions are all in reverse order, you can arrange them in this way
    private static int[] reverse(int[] num,int index){
        for (int i = index,j = num.length -1;i < j;i++,j--) {
            int temp = num[i];
            num[i] = num[j];
            num[j] = temp;
        }
        return num;
    }

    public static void main(String[] args){
        int[] numbers = {1,2,3,4,5};
        for(int i = 0;i < 10;i++){
            numbers = findNearestNumber(numbers);
            outputNumbers(numbers);
        }
    }

    private static void outputNumbers(int[] numbers){
        for(int i : numbers){
            System.out.print(i);
        }
        System.out.println();
    }

}

Posted by JesperBisgaard on Fri, 29 Nov 2019 21:20:25 -0800