找到字符串的下一个最高的lexicgraphic排列

时间:2016-11-17 08:00:48

标签: python algorithm lexicographic-ordering

给定一个字符串W,我想要在字典上实现其下一个字符串更大。

eg 1:
givenstring = "hegf"
nexthighest = "hefg"

我到现在为止所尝试的是,

from itertools import permutations
q = int(input())
for i in range(q):
    s = input()
    if s == s[::-1]:
        print("no answer")
    else:
        x = ["".join(p) for p in list(permutations(s))]
        x.sort()
        index = x.index(s)
        print(x[index+1])

因为这不是解决这个问题的有效方法。请你建议我更好的方法来解决这个问题

2 个答案:

答案 0 :(得分:0)

这是解决此问题的另一种方法

def NextHighestWord(string):
    S = [ord(i) for i in string]
    #find non-incresing suffix from last
    i = len(S) - 1
    while i > 0 and S[i-1] >= S[i]:
        i = i - 1
    if i <= 0:
        return False

    #next element to highest is pivot
    j = len(S) - 1
    while S[j] <= S[i -1]:
        j = j - 1
    S[i-1],S[j] = S[j],S[i-1]

    #reverse the suffix
    S[i:] = S[len(S) - 1 : i-1 : -1]
    ans = [chr(i) for i in S]
    ans = "".join(ans)
    print(ans)
    return True

test = int(input())
for i in range(test):
    s = input()
    val = NextHighestWord(s)
    if val:
        continue
    else:
        print("no answer")

答案 1 :(得分:0)

生成下一个排列的一种经典算法是:

Step 1: Find the largest index k, such that A[k] < A[k + 1]. 
        If not exist, this is the last permutation. (in this problem just reverse the vector and return.)
Step 2: Find the largest index l, such that A[l] > A[k] and l > k.
Step 3: Swap A[k] and A[l].
Step 4: Reverse A[k + 1] to the end.

这是我上面算法的C ++片段。虽然它不是python,但语法简单且伪代码相似,希望你能得到这个想法。

void nextPermutation(vector<int> &num) {
    int k = -1;
    int l;
    //step1
    for (int i = num.size() - 1; i > 0; --i) {
        if (num[i - 1] < num[i]) {
            k = i - 1;
            break;
        }
    }
    if (k == -1) {
        reverse(num.begin(), num.end());
        return;
    }

    //step2
    for (int i = num.size() - 1; i > k; --i) {
        if (num[i] > num[k]) {
            l = i;
            break;
        }
    }
    //step3
    swap(num[l], num[k]);

    //step4
    reverse(num.begin() + k + 1, num.end());
}