我很少有像'hefg','dhck','dkhc','lmno'
这样的单词(字符串),可以通过交换一些或所有字符来转换成新单词,以使新单词在字典上大于原始单词,而且新单词最少大于原始单词的所有单词。
例如'dhck'
应该输出'dhkc'
而不是'kdhc'
,'dchk'
或其他任何值。
我有这些输入
hefg
dhck
dkhc
fedcbabcd
应输出
hegf
dhkc
hcdk
fedcbabdc
我已经尝试在python中使用此代码,该代码可用于'dkhc'
和'fedcbabcd'
以外的所有代码。
我发现'fedcbabcd'
的第一个字符是最大值,因此不会被交换。
我正在"ValueError: min() arg is an empty sequence"
如何修改算法以解决问题?
list1=['d','k','h','c']
list2=[]
maxVal=list1.index(max(list1))
for i in range(maxVal):
temp=list1[maxVal]
list1[maxVal]=list1[i-1]
list1[i-1]=temp
list2.append(''.join(list1))
print(min(list2))
答案 0 :(得分:2)
您可以尝试以下操作:
示例代码:
def next_word(word):
word = list(word)
seen = {}
for i in range(len(word)-1, -1, -1):
if any(x > word[i] for x in seen):
x = min(x for x in seen if x > word[i])
word[i], word[seen[x]] = word[seen[x]], word[i]
return ''.join(word[:i+1] + sorted(word[i+1:]))
if word[i] not in seen:
seen[word[i]] = i
for word in ["hefg", "dhck", "dkhc", "fedcbabcd"]:
print(word, next_word(word))
结果:
hefg hegf
dhck dhkc
dkhc hcdk
fedcbabcd fedcbabdc
答案 1 :(得分:2)
在一般情况下,最大字符及其位置不影响算法。例如,对于'fedcbabcd'
,您可以在字符串的开头加上a
或z
,这不会改变您需要交换最后两个字母的事实。
考虑输入'dgfecba'
。在这里,输出为'eabcdfg'
。为什么?请注意,最后六个字母是按降序排列的,因此,通过在此处更改任何内容,您将在字典上得到一个较小的字符串,这是不好的。因此,您需要替换初始的'd'
。我们应该把它放在什么位置?我们想要比'd'
大的东西,但要尽可能小,所以'e'
。剩下的六个字母呢?同样,我们想要一个尽可能小的字符串,所以我们按字母顺序对字母进行排序:'eabcdfg'
。
所以算法是:
i
在s[i] < s[i + 1]
的最右边;在我们的例子中,i
= 0; i
上的符号-1保持不变; i+1 ... n-1
中找出包含大于s[i]
的最小符号的位置;将此职位称为j
;在我们的例子中,j
= 3; s[i]
和s[j]
;在我们的情况下,我们获得'egfdcba'
; s[i+1] ... s[n-1]
;在我们的情况下,我们获得'eabcdfg'
。答案 2 :(得分:0)
您的问题可以改写为finding the next lexicographical permutation of a string。
上面链接中的算法描述如下:
1)找到最长的不增加后缀
2)左边的数字 后缀是我们的关键
3)在中找到枢轴的最右后继 后缀
4)交换后继者和支点
5)反转后缀
上述算法特别有趣,因为它是 O(n)。
def next_lexicographical(word):
word = list(word)
# Find the pivot and the successor
pivot = next(i for i in range(len(word) - 2, -1, -1) if word[i] < word[i+1])
successor = next(i for i in range(len(word) - 1, pivot, -1) if word[i] > word[pivot])
# Swap the pivot and the successor
word[pivot], word[successor] = word[successor], word[pivot]
# Reverse the suffix
word[pivot+1:] = word[-1:pivot:-1]
# Reform the word and return it
return ''.join(word)
如果单词已经是最后的字典排列,则上述算法将引发StopIteration
异常。
words = [
'hefg',
'dhck',
'dkhc',
'fedcbabcd'
]
for word in words:
print(next_lexicographical(word))
hegf
dhkc
hcdk
fedcbabdc