Finding the index of a given permutation

前端 未结 7 543
闹比i
闹比i 2020-12-10 15:38

I\'m reading the numbers 0, 1, ..., (N - 1) one by one in some order. My goal is to find the lexicography index of this given permutation, using only O(1)

相关标签:
7条回答
  • 2020-12-10 16:26

    Considering the following data:

    chars = [a, b, c, d]
    perm = [c, d, a, b]
    ids = get_indexes(perm, chars) = [2, 3, 0, 1]
    

    A possible solution for permutation with repetitions goes as follows:

    len = length(perm)         (len = 4)
    num_chars = length(chars)  (len = 4)
    
    base = num_chars ^ len     (base = 4 ^ 4 = 256)
    base = base / len          (base = 256 / 4 = 64)
    
    id = base * ids[0]         (id = 64 * 2 = 128)
    base = base / len          (base = 64 / 4 = 16)
    
    id = id + (base * ids[1])  (id = 128 + (16 * 3) = 176)
    base = base / len          (base = 16 / 4 = 4)
    
    id = id + (base * ids[2])  (id = 176 + (4 * 0) = 176)
    base = base / len          (base = 4 / 4 = 1)
    
    id = id + (base * ids[3])  (id = 176 + (1 * 1) = 177)
    

    Reverse process:

    id = 177
    (id / (4 ^ 3)) % 4 = (177 / 64) % 4 =   2 % 4 = 2 -> chars[2] -> c
    (id / (4 ^ 2)) % 4 = (177 / 16) % 4 =  11 % 4 = 3 -> chars[3] -> d
    (id / (4 ^ 1)) % 4 = (177 / 4)  % 4 =  44 % 4 = 0 -> chars[0] -> a
    (id / (4 ^ 0)) % 4 = (177 / 1)  % 4 = 177 % 4 = 1 -> chars[1] -> b
    

    The number of possible permutations is given by num_chars ^ num_perm_digits, having num_chars as the number of possible characters, and num_perm_digits as the number of digits in a permutation.

    This requires O(1) in space, considering the initial list as a constant cost; and it requires O(N) in time, considering N as the number of digits your permutation will have.

    Based on the steps above, you can do:

    function identify_permutation(perm, chars) {
    
        for (i = 0; i < length(perm); i++) {
            ids[i] = get_index(perm[i], chars);
        }
    
        len = length(perm);
        num_chars = length(chars);
    
        index = 0;
        base = num_chars ^ len - 1;
        for (i = 0; i < length(perm); i++) {
            index += base * ids[i];
            base = base / len;
        }
    
    }
    

    It's a pseudocode, but it's also quite easy to convert to any language (:

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