应该删除给定字符串S中的最少字符数,以使其成为已排序的字符串[重复]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应该删除给定字符串S中的最少字符数,以使其成为已排序的字符串[重复]相关的知识,希望对你有一定的参考价值。
我需要找到使字符串排序所需的最小删除次数。
样本测试案例:
# Given Input:
teststr = "abcb"
# Expected output:
1
# Explanation
# In this test case, if I delete last 'b' from "abcb",
# then the remaining string "abc" is sorted.
# That is, a single deletion is required.
# Given Input:
teststr = "vwzyx"
# Expected output:
2
# Explanation
# Here, if I delete 'z' and 'x' from "vwzyx",
# then the remaining string "vwy" is a sorted string.
我尝试了以下但它超出了时间限制错误。还有其他方法可以解决这个问题
string = input()
prev_ord = ord(string[0])
deletion = 0
for char in string[1:]:
if ord(char) > prev_ord +1 or ord(char) < prev_ord:
deletion += 1
continue
prev_ord = ord(char)
print(deletion)
您当前的算法将为许多字符串提供不正确的结果。
我怀疑有一种更有效的方法可以解决这个问题,但这是一个蛮力的解决方案。它生成输入字符串的子集,按长度排序,降序。子集中的元素保留原始字符串的顺序。一旦count_deletions
找到一个有序的子集,它就会返回它(转换回一个字符串),以及删除的数量。因此,它找到的解决方案保证不会短于输入字符串的任何其他排序选择。
有关我使用的各种itertools
docs函数的信息,请参阅itertools
;用于生成子集的算法源自powerset
部分中的Recipes示例。
from itertools import chain, combinations
def count_deletions(s):
for t in chain.from_iterable(combinations(s, r) for r in range(len(s), 0, -1)):
t = list(t)
if t == sorted(t):
return ''.join(t), len(s) - len(t)
# Some test data.
data = [
"abcdefg",
"cba",
"abcb",
"vwzyx",
"zvwzyx",
"adabcef",
"fantastic",
]
for s in data:
print(s, count_deletions(s))
产量
abcdefg ('abcdefg', 0)
cba ('c', 2)
abcb ('abc', 1)
vwzyx ('vwz', 2)
zvwzyx ('vwz', 3)
adabcef ('aabcef', 1)
fantastic ('fntt', 5)
该数据集不足以完全测试旨在解决此问题的算法,但我想这是一个不错的起点。 :)
Update
这是Salvador Dali在链接页面上提到的算法的Python 3实现。它比我以前的蛮力方法快得多,特别是对于更长的琴弦。
我们可以通过对字符串的副本进行排序,然后找到原始字符串和排序字符串的最长公共子序列(LCS)来找到最长排序的子序列。 Salvador的版本从排序的字符串中删除了重复的元素,因为他希望结果严格增加,但我们不需要这里。
此代码仅返回所需的删除次数,但很容易修改它以返回实际排序的字符串。
为了使这个递归函数更有效,它使用functools的lru_cache
装饰器。
from functools import lru_cache
@lru_cache(maxsize=None)
def lcs_len(x, y):
if not x or not y:
return 0
xhead, xtail = x[0], x[1:]
yhead, ytail = y[0], y[1:]
if xhead == yhead:
return 1 + lcs_len(xtail, ytail)
return max(lcs_len(x, ytail), lcs_len(xtail, y))
def count_deletions(s):
lcs_len.cache_clear()
return len(s) - lcs_len(s, ''.join(sorted(s)))
data = [
"abcdefg",
"cba",
"abcb",
"vwzyx",
"zvwzyx",
"adabcef",
"fantastic",
]
for s in data:
print(s, count_deletions(s))
产量
abcdefg 0
cba 2
abcb 1
vwzyx 2
zvwzyx 3
adabcef 1
fantastic 5
希望它适用于所有情况:)
s = input()
s_2 = ''.join(sorted(set(s), key=s.index))
sorted_string = sorted(s_2)
str_to_list = list(s_2)
dif = 0
for i in range(len(sorted_string)):
if sorted_string[i]!=str_to_list[i]:
dif+=1
print(dif+abs(len(s)-len(s_2)))
以上是关于应该删除给定字符串S中的最少字符数,以使其成为已排序的字符串[重复]的主要内容,如果未能解决你的问题,请参考以下文章
构造回文 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢? 输出需要删除的字符个数。