编码挑战
挑战:给定一个字符串。如何找到该字符串中的所有调弦词?
为了便于理解,请允许我快速添加一个关于宫格词的定义。
定义:回文是指前后读数相同的字符序列,如: , , 或 。'madam' 'anna' '101'
本文想在Python中给你一个快速而简单的解决方案。首先,我们将解决一个比较容易但重要的问题,即首先检查一个子串是否是宫格。
如何检查字符串是否是回文
通过使用切片表达式word == word[::-1] ,你可以很容易地检查一个字符串是否是一个回文,如果这个词向前和向后都是一样的,即它是一个回文,那么这个表达式的评估值为True 。
接下来,我们将探讨如何在一个Python字符串中找到所有也是宫格的子串。你可以在代码解决方案中找到我们的宫格检查器(突出显示)。
查找所有同为宫格的子串
寻找一个字符串中的所有重音符的简单方法是在一个嵌套的循环中遍历所有子串。 [for](https://blog.finxter.com/python-loops/)循环遍历所有子串。然后使用word == word[::-1] ,检查每一个子串是否是一个宫格。使用下面的方法来跟踪找到的重名词 [list.append()](https://blog.finxter.com/python-list-append/)的方法来跟踪找到的同调词。在遍历所有子串后返回最终的列表。
这里是完整的解决方案。
def find_palindromes(s):
palindromes = []
n = len(s)
for i in range(n):
for j in range(i+1,n+1):
word = s[i:j]
if word == word[::-1]:
palindromes.append(word)
return palindromes
print(find_palindromes('locoannamadam'))
# ['l', 'o', 'oco', 'c', 'o', 'a', 'anna',
# 'n', 'nn', 'n', 'a', 'ama', 'm', 'madam',
# 'a', 'ada', 'd', 'a', 'm']
print(find_palindromes('anna'))
# ['a', 'anna', 'n', 'nn', 'n', 'a']
print(find_palindromes('abc'))
# ['a', 'b', 'c']
运行时复杂度
这具有立方的运行时间复杂性,即对于一个长度为n 的字符串,我们需要检查O(n*n) 不同的单词。每个词可能有多达n 个字符,因此回文检查本身就是O(n) 。这就产生了运行时复杂度为O(n*n*n) = O(n³) 。
二次方运行时间解决方案
这就是我们能做的最好的了吗?不是的!还有一个O(n)还有一个O(n²)时间的解决方案!
这里有一个二次运行时间的解决方案,可以在给定的字符串中找到所有的回文,忽略了琐碎的单字回文(从源头上做了重大修改)。
def find_palindromes(s, j, k):
''' Finds palindromes in substring between indices j and k'''
palindromes = []
while j >= 0 and k < len(s):
if s[j] != s[k]:
break
palindromes.append(s[j: k + 1])
j -= 1
k += 1
return palindromes
def find_all(s):
'''Finds all palindromes (non-trivial) in string s'''
palindromes = []
for i in range(0, len(s)):
palindromes.extend(find_palindromes(s, i-1, i+1))
palindromes.extend(find_palindromes(s, i, i+1))
return palindromes
print(find_all('locoannamadam'))
# ['oco', 'nn', 'anna', 'ama', 'ada', 'madam']
print(find_all('anna'))
# ['nn', 'anna']
print(find_all('abc'))
# []