我对 python 代码的一部分感到困惑
I am confused in a part of my python code
Q-给定一个在 ascii[a-z] 范围内的小写字母字符串,确定一个字符的索引,可以删除该字符以使该字符串成为回文。可能有不止一种解决方案,但任何一种都可以。如果这个词已经是回文或者无解,return-1。否则,return 要删除的字符的索引。
任何人都可以告诉我在我的这段代码中 s[i] != s[n-1-i]
部分发生了什么。
def palindromeIndex(s):
if s == s[::-1]:
return -1
n=len(s)
for i in range(n//2):
if s[i] != s[n-1-i]:
if s[i:n-1-i]==s[i:n-1-i][::-1]:
return n-1-i
elif s[i+1:n-i]==s[i+1:n-i][::-1]:
return i
return -1
我主要是在这些地方感到困惑
for i in range(n//2):
if s[i] != s[n-1-i]:
if s[i:n-1-i]==s[i:n-1-i][::-1]:
return n-1-i
elif s[i+1:n-i]==s[i+1:n-i][::-1]:
return i
所以i
是当前索引,遍历字符串的前半部分。
s[i]
是该索引处的字母,s[n-1-i]
将是第 n-1-i
位置的字母。由于 n=len(s)
,n-1
将是字符串中的最后一个字符,我们将从那里向后返回 i
。例如,如果我们使用字符串 foobar
和 i=1
,则 s[i]
将是 o
,而 s[n-1-i]
将是 a
。那是第一个 if
语句 - 检测第一个 i
处我们不再是回文,即从前面开始的第 i
个字符与 i
从末尾算起第 ] 个字符。
一旦我们确定这对字符不匹配,我们需要确定删除其中任何一个是否会使我们的字符串再次成为回文。有两种可能的情况可以实现这一点:
- 删除
n-1-i
处的字母会使字符串回文
- 删除
i
处的字母会使字符串回文
我们按顺序尝试这两种情况。然而,与其重新创建整个输入字符串,减去一个字母,我们可以通过仅测试当前端点之间的子字符串的回文性而不是整个字符串来巧妙地节省内存。毕竟,我们知道当前 i
- n-1-i
对之外的所有内容都已经是回文。这就是您在 if
语句中看到的奇妙魔法 - 测试子串的回文性。
s[i:n-1-i]==s[i:n-1-i][::-1]
可以分解成几个部分。首先,s[i:n-1-i]
是我们的 i
和 n-1-i
标记之间的子字符串,但不包括 n-1-i
处的字母。我们称之为 sub
。将其替换回来后,我们有 sub == sub[::-1]
。正如您从前面的函数中认识到的那样,这就是您测试给定字符串是否为回文的方式。如果 sub
是回文,那么您知道,通过省略 n-1-i
处的字符,您的整个原始字符串都是回文。因此,我们 return n-1-i
.
s[i+1:n-i]==s[i+1:n-i][::-1]
的分解方式大致相同。不同之处在于 s[i+1:n-i]
向右移动了一个字符,因此结果是我们的 i
和 n-1-i
标记之间的子字符串,但这次不包括 [=11= 处的字母] 并包括 s[n-1-i]
处的那个。如果这个子串是回文串,那么我们就知道 s[i]
处的字母必须去掉才能使原始串成为回文串。因此,我们returni
如果以上两种情况都不成立,那么不仅输入字符串不是回文,而且无法只删除一个字母使其成为回文。所以,我们return-1
表示无解
Q-给定一个在 ascii[a-z] 范围内的小写字母字符串,确定一个字符的索引,可以删除该字符以使该字符串成为回文。可能有不止一种解决方案,但任何一种都可以。如果这个词已经是回文或者无解,return-1。否则,return 要删除的字符的索引。
任何人都可以告诉我在我的这段代码中 s[i] != s[n-1-i]
部分发生了什么。
def palindromeIndex(s):
if s == s[::-1]:
return -1
n=len(s)
for i in range(n//2):
if s[i] != s[n-1-i]:
if s[i:n-1-i]==s[i:n-1-i][::-1]:
return n-1-i
elif s[i+1:n-i]==s[i+1:n-i][::-1]:
return i
return -1
我主要是在这些地方感到困惑
for i in range(n//2):
if s[i] != s[n-1-i]:
if s[i:n-1-i]==s[i:n-1-i][::-1]:
return n-1-i
elif s[i+1:n-i]==s[i+1:n-i][::-1]:
return i
所以i
是当前索引,遍历字符串的前半部分。
s[i]
是该索引处的字母,s[n-1-i]
将是第 n-1-i
位置的字母。由于 n=len(s)
,n-1
将是字符串中的最后一个字符,我们将从那里向后返回 i
。例如,如果我们使用字符串 foobar
和 i=1
,则 s[i]
将是 o
,而 s[n-1-i]
将是 a
。那是第一个 if
语句 - 检测第一个 i
处我们不再是回文,即从前面开始的第 i
个字符与 i
从末尾算起第 ] 个字符。
一旦我们确定这对字符不匹配,我们需要确定删除其中任何一个是否会使我们的字符串再次成为回文。有两种可能的情况可以实现这一点:
- 删除
n-1-i
处的字母会使字符串回文 - 删除
i
处的字母会使字符串回文
我们按顺序尝试这两种情况。然而,与其重新创建整个输入字符串,减去一个字母,我们可以通过仅测试当前端点之间的子字符串的回文性而不是整个字符串来巧妙地节省内存。毕竟,我们知道当前 i
- n-1-i
对之外的所有内容都已经是回文。这就是您在 if
语句中看到的奇妙魔法 - 测试子串的回文性。
s[i:n-1-i]==s[i:n-1-i][::-1]
可以分解成几个部分。首先,s[i:n-1-i]
是我们的 i
和 n-1-i
标记之间的子字符串,但不包括 n-1-i
处的字母。我们称之为 sub
。将其替换回来后,我们有 sub == sub[::-1]
。正如您从前面的函数中认识到的那样,这就是您测试给定字符串是否为回文的方式。如果 sub
是回文,那么您知道,通过省略 n-1-i
处的字符,您的整个原始字符串都是回文。因此,我们 return n-1-i
.
s[i+1:n-i]==s[i+1:n-i][::-1]
的分解方式大致相同。不同之处在于 s[i+1:n-i]
向右移动了一个字符,因此结果是我们的 i
和 n-1-i
标记之间的子字符串,但这次不包括 [=11= 处的字母] 并包括 s[n-1-i]
处的那个。如果这个子串是回文串,那么我们就知道 s[i]
处的字母必须去掉才能使原始串成为回文串。因此,我们returni
如果以上两种情况都不成立,那么不仅输入字符串不是回文,而且无法只删除一个字母使其成为回文。所以,我们return-1
表示无解