Given a number n, list all n-digit numbers such that each number does not have repeating digits

Maribell Pina Griego :

I'm trying to solve the following problem. Given an integer, n, list all n-digits numbers such that each number does not have repeating digits.

For example, if n is 4, then the output is as follows:

0123
0124
0125
...
9875
9876
Total number of 4-digit numbers is 5040

My present approach is by brute-force. I can generate all n-digit numbers, then, using a Set, list all numbers with no repeating digits. However, I'm pretty sure there is a faster, better and more elegant way of doing this.

I'm programming in Java, but I can read source code in C.

Thanks

John Humphreys - w00te :

Mathematically, you have 10 options for the first number, 9 for the second, 8 for the 3rd, and 7 for the 4th. So, 10 * 9 * 8 * 7 = 5040.

Programmatically, you can generate these with some combinations logic. Using a functional approach usually keeps code cleaner; meaning build up a new string recursively as opposed to trying to use a StringBuilder or array to keep modifying your existing string.

Example Code

The following code will generate the permutations, without reusing digits, without any extra set or map/etc.

public class LockerNumberNoRepeats {
    public static void main(String[] args) {
        System.out.println("Total combinations = " + permutations(4));
    }

    public static int permutations(int targetLength) {
        return permutations("", "0123456789", targetLength);
    }

    private static int permutations(String c, String r, int targetLength) {
        if (c.length() == targetLength) {
            System.out.println(c);
            return 1;
        }

        int sum = 0;
        for (int i = 0; i < r.length(); ++i) {
            sum += permutations(c + r.charAt(i), r.substring(0,i) + r.substring(i + 1), targetLength);
        }
        return sum;
    }
}

Output:

...
9875
9876
Total combinations = 5040

Explanation

Pulling this from a comment by @Rick as it was very well said and helps to clarify the solution.

So to explain what is happening here - it's recursing a function which takes three parameters: a list of digits we've already used (the string we're building - c), a list of digits we haven't used yet (the string r) and the target depth or length. Then when a digit is used, it is added to c and removed from r for subsequent recursive calls, so you don't need to check if it is already used, because you only pass in those which haven't already been used.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=108005&siteId=1