Checking whether two numbers are permutation of each other?

前端 未结 7 2036
借酒劲吻你
借酒劲吻你 2021-02-15 22:44

Given two numbers a, b such that 1 <= a , b <= 10000000000 (10^10). My problem is to check whether the digits in them are permutation of each other or not. What is the fas

相关标签:
7条回答
  • 2021-02-15 23:26

    Well if you can build an 80GB table, you could always do:

    int64 table[10000000000] = {0, blah blah..., 9999999999};
    
    if (table[a] == table[b]) ...
    
    0 讨论(0)
  • 2021-02-15 23:26

    Create an array:

    int digitOccurances[2][10];
    

    In digitOccruances[X][N] store the number of times that the digit N appears in the number X. So if you were comparing 8675309 to 9568733, the array would end up looking like:

    { { 1, 0, 0, 1, 0, 1, 1, 1, 1, 1 } , { 0, 0, 0, 2, 0, 1, 1, 1, 1, 1 } }
    

    If the two arrays are equal, then the numbers are permutations.

    This is an O(n) algorithm, so asymptotically speaking this is the most efficient it's going to get (you can't solve this problem without examining all of the digits at least once.

    You can immediately return false if the numbers have different lengths, so assume that both of are of length n. It will take 2n operations to fill the array, and then exactly 10 comparisons to read the array. 2n + 10 is O(n).

    0 讨论(0)
  • 2021-02-15 23:31

    I've found this rather efficient solution on rossetacode.org. I hope you'll forgive me for writing it in Java (I'm not comfortable with C) but the syntax should be more or less the same.

    The code first checks to see if the numbers have the same number of digits, then sums up the digits by bit shifting them into a total. Except the shift distance is multiplied by a factor 6. This makes it impossible for smaller digits to compose the same value as a larger digit. For instance one '9' would require 64 times '8' to match its value, which obviously isn't possible.

    This code assumes non-negative input.

    boolean haveSameDigits(long n1, long n2) {
        long nn1 = n1, nn2 = n2;
        while (nn1 > 0 && nn2 > 0) {
            nn1 /= 10;
            nn2 /= 10;
        }
        if (nn2 != nn1) // not the same length
            return false;
    
        long total1 = 0, total2 = 0;
        while (n1 != 0) {
            total1 += 1L << ((n1 % 10) * 6);
            total2 += 1L << ((n2 % 10) * 6);
            n1 /= 10;
            n2 /= 10;
        }
        return total1 == total2;
    }
    
    0 讨论(0)
  • 2021-02-15 23:36

    a and b are anagrams if they have the same number of each digit. So basically the fastest way seems to be, counting the digits for a and b:

    int c[10]={0,0,0,0,0,0,0,0,0,0}
    
    while (a) { c[a%10]++; a/=10; }
    while (b) { c[b%10]--; b/=10; }
    
    int res=1;
    for (int i=0;i<10;i++) res &= c[i]==0;
    printf(res?"yes":"no");
    
    0 讨论(0)
  • 2021-02-15 23:41

    Is it homework?

    Calculate number of appearances of each digit and compare them, if they are same then one number can be converted to other using permutation.

    0 讨论(0)
  • 2021-02-15 23:46

    If what i understood from your question correctly a permutation is a combination of the elements, which do not repeat. So if 123 is a valid permutation of 312 then so does

    123,
    213,
    132,
    321,
    213, 
    

    and so on.

    So based on this assumption lets say you got two integers 123456789 and 129837456. (For simplicity i am also assuming that both numbers have equal length). If you understood the point then you might be able to check for different permutations and combination as well.

    for that all you need to do is to get the integers of units out of the given number, e.g:

    Number 123456789 is
    1 * 100000000 + 
    2 * 10000000  +
    3 * 1000000   +
    4 * 100000    +
    5 * 10000     +
    6 * 1000      +
    7 * 100       +
    8 * 10        +
    9 
    

    or

    1 * power(10, 8) +
    2 * power(10, 7) +
    3 * power(10, 6) +
    4 * power(10, 5) +
    5 * power(10, 4) +
    6 * power(10, 3) +
    7 * power(10, 2) +
    8 * power(10, 1) +
    9 * power(10, 0) 
    

    i have literally given you algorithmic hint of how to do that so this can easily be done. once done you will end up with separate integers (better save these values in an array)

    1, 2, 3, 4, 5, 6, 7, 8, 9
    

    Now

    do the same for the other given integer so you will end up with another array of integers

    1, 2, 9, 8, 3, 7, 4, 5, 6
    

    so now all you need to check is that if all of the integers of the second array are present in the first array of integers, if yes then they are a permutation of the integers of the first array or the first number.

    I hope this helps.

    0 讨论(0)
提交回复
热议问题