力扣题目链接
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
版本一:双指针
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left, right = 0, len(s) - 1
# 该方法已经不需要判断奇偶数,经测试后时间空间复杂度比用 for i in range(len(s)//2) 更低
# 因为 while 每次循环需要进行条件判断,而 range 函数不需要,直接生成数字,因此时间复杂度更低。推荐使用 range
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
class Solution:
:这是一个类定义,通常在LeetCode中用于将解决方案封装成一个类的形式。解决方案通常是作为类的方法来实现的。
def reverseString(self, s: List[str]) -> None:
:这是一个方法定义,用于反转输入的字符串列表 s
。self
是类方法的第一个参数,表示该方法是一个成员方法。s
是输入参数,它是一个字符串列表。-> None
表示这个方法不返回任何值,它会在原地修改输入的字符串列表。
left, right = 0, len(s) - 1
:这一行代码初始化两个指针 left
和 right
,它们分别指向字符串列表的开头和末尾。left
初始化为0,表示字符串列表的第一个元素,right
初始化为 len(s) - 1
,表示字符串列表的最后一个元素。
while left < right:
:这是一个 while
循环,它的条件是 left
指针小于 right
指针,意味着只要 left
还在 right
的左边,就继续执行循环。
s[left], s[right] = s[right], s[left]
:这一行代码实际上是交换了 left
指针和 right
指针指向的元素的值。通过使用 Python 的多重赋值特性,可以很方便地交换两个变量的值,这里用于交换字符串列表中对应位置的元素。
left += 1
和 right -= 1
:这两行代码分别将 left
指针向右移动一位,将 right
指针向左移动一位,以便继续下一次循环,直到完成整个字符串列表的反转。
总的来说,这段代码使用了双指针的方法,从字符串列表的两端开始,逐渐向中间移动,并交换元素的值,最终实现了字符串列表的反转。这种方法是一种常见的反转列表的方式,它的时间复杂度是 O(n),其中 n 是字符串列表的长度。
版本二:使用栈
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
stack = [] # 创建一个空栈
for char in s:
stack.append(char) # 将字符依次入栈
for i in range(len(s)):
s[i] = stack.pop() # 从栈中弹出字符并赋值给原字符串列表,实现反转
栈 = []
:创建一个空的栈(堆栈)。
for char in s:
:遍历输入的字符串列表 s
中的每个字符,将它们依次添加到栈中。
for i in range(len(s)):
:通过索引 i
遍历整个字符串列表 s
。
s[i] = 栈.pop()
:从栈中弹出最后一个字符,并将其赋值给字符串列表 s
中的当前位置 i
,从而实现了字符串列表的反转。
这种方法的时间复杂度为 O(n),其中 n 是字符串列表的长度,因为我们对字符串列表进行了两次完整的遍历。空间复杂度为 O(n),因为我们使用了一个额外的栈数据结构来存储字符。这是一种简单而直观的方法来反转字符串列表。
版本三:使用range
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
n = len(s) # 获取字符串列表的长度
for i in range(n // 2): # 只需要遍历一半的列表
s[i], s[n - i - 1] = s[n - i - 1], s[i] # 交换对应位置的元素
n = len(s)
:获取输入字符串列表 s
的长度,并将其存储在变量 n
中。这个长度将帮助我们确定需要遍历多少次来完成反转。
for i in range(n // 2):
:这是一个 for
循环,它只需要遍历一半的列表,因为在反转的过程中,前半部分的元素会与后半部分的元素进行交换,反转完成后列表就会变为原来的逆序。
s[i], s[n - i - 1] = s[n - i - 1], s[i]
:这一行代码使用了多重赋值的方式,将前半部分 s[i]
和后半部分 s[n - i - 1]
的值进行交换。这个操作会将列表中对应位置的元素进行反转
版本四:使用reverse
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s[:] = reversed(s)
s[:] = s[::-1]
:这一行代码使用了 Python 的切片(slicing)操作来反转列表 s
。具体来说,s[::-1]
表示一个切片,它从最后一个元素到第一个元素,以逆序的方式提取元素。然后,s[:]
表示将切片的结果重新赋值给列表 s
,这样就完成了列表的反转。
版本五:使用列表
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s[:] = [s[i] for i in range(len(s) - 1, -1, -1)]
[s[i] for i in range(len(s) - 1, -1, -1)]
:这是一个列表推导式,它遍历了从 len(s) - 1
到 0
的索引范围,以逆序的方式提取字符串列表 s
中的元素,并将它们构建成一个新的列表。这个新列表就是原列表的逆序版本。
s[:]
:这是一个切片操作,它将新的逆序列表重新赋值给原列表 s
,从而实现了字符串列表的反转。
力扣题目链接
给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例:
输入: s = "abcdefg", k = 2
输出: "bacdfeg"
class Solution:
def reverseStr(self, s: str, k: int) -> str:
"""
1. 使用range(start, end, step)来确定需要调换的初始位置
2. 对于字符串s = 'abc',如果使用s[0:999] ===> 'abc'。字符串末尾如果超过最大长度,则会返回至字符串最后一个值,这个特性可以避免一些边界条件的处理。
3. 用切片整体替换,而不是一个个替换.
"""
def reverse_substring(text):
left, right = 0, len(text) - 1
while left < right:
text[left], text[right] = text[right], text[left]
left += 1
right -= 1
return text
res = list(s) # 将输入字符串转换为字符列表,以便后续修改
for cur in range(0, len(s), 2 * k): # 以 2*k 为步长遍历字符串
res[cur: cur + k] = reverse_substring(res[cur: cur + k]) # 对每个块内的字符进行反转
return ''.join(res) # 将字符列表转换回字符串并返回
reverse_substring(text)
函数:这个函数接受一个字符串 text
,然后使用双指针技巧反转字符串。它通过不断交换字符来实现反转,最终返回反转后的字符串。
res = list(s)
:这一行代码将输入的字符串 s
转换为字符列表 res
,以便后续可以通过索引修改其中的字符。
for cur in range(0, len(s), 2 * k)
:这是一个 for
循环,它以步长 2 * k
遍历字符串,其中 cur
是当前块的起始位置。每次循环处理一个块。
res[cur: cur + k] = reverse_substring(res[cur: cur + k])
:在循环内部,对每个块的字符列表进行了反转操作。具体来说,它使用 reverse_substring
函数对当前块内的字符进行反转,并将反转后的结果赋值回 res
列表中的相应位置。
return ''.join(res)
:最后,将字符列表 res
转换回字符串,并返回最终的结果。
这段代码的主要思路是将字符串分成块,对每个块内的字符进行反转,最后将块拼接在一起。这样就实现了按照长度为 k
的块进行反转的操作。时间复杂度取决于字符串的长度,但是对于每个块内的字符反转,它的时间复杂度是 O(k),因此总的时间复杂度是 O(n),其中 n 是字符串的长度。
力扣题目链接(opens new window)
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1: 输入:s = "We are happy."
输出:"We%20are%20happy."
法一:添加空列表,添加匹配的结果
class Solution:
def replaceSpace(self, s: str) -> str:
res = []
for i in range(len(s)):
if s[i] == ' ':
res.append('%20')
else:
res.append(s[i])
return ''.join(res)
res = []
:这一行代码创建一个空的列表 res
,用于存储替换后的字符。
for i in range(len(s)):
:这是一个 for
循环,它遍历字符串 s
中的每个字符,使用索引 i
来访问每个字符。
在循环内部,使用条件语句检查当前字符是否是空格 s[i] == ' '
。如果是空格,就执行以下操作:
res.append('%20')
:将 %20
添加到列表 res
中,以替换空格。如果当前字符不是空格(else
分支),就执行以下操作:
res.append(s[i])
:将原字符添加到列表 res
中,以保持字符不变。return ''.join(res)
:最后,将列表中的字符使用 join
方法拼接成一个字符串,并返回这个字符串作为结果。
法二:使用replace
class Solution:
def replaceSpace(self, s: str) -> str:
s.replace(' ', '%20')
:这一行代码调用了字符串 s
的 replace
方法,用于将字符串中的空格 ' '
替换为 %20
。这个方法会返回一个新的字符串,其中空格被替换为 %20
。
力扣题目链接
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
class Solution:
def reverseWords(self, s: str) -> str:
# 删除前后空白
s = s.strip()
# 反转整个字符串
s = s[::-1]
# 将字符串拆分为单词,并反转每个单词
s = ' '.join(word[::-1] for word in s.split())
return s
s = s.strip()
:这一行代码用于删除字符串两端的空白字符(包括空格、制表符和换行符等),确保字符串没有前导和尾随的空格。
s = s[::-1]
:这一行代码通过切片操作将整个字符串反转。[::-1]
表示从字符串末尾向前逆序遍历,实现字符串反转。
s = ' '.join(word[::-1] for word in s.split())
:这一行代码实现了将字符串拆分为单词,并反转每个单词后重新拼接成字符串。具体操作如下:
s.split()
:将字符串按照空格拆分成一个单词列表。word[::-1] for word in s.split()
:使用列表推导式,对每个单词进行反转,得到一个反转后的单词列表。' '.join(...)
:将反转后的单词列表用空格拼接成一个字符串,这样单词之间仍然以空格分隔。力扣题目链接
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
return s[n:] + s[:n]
s[n:]
:这部分代码表示从字符串 s
的第 n
个字符开始到末尾的子字符串。它实际上提取了字符串 s
中从第 n
个字符到末尾的部分。
s[:n]
:这部分代码表示从字符串 s
的开头到第 n
个字符的子字符串。它实际上提取了字符串 s
中从开头到第 n
个字符的部分。
s[n:] + s[:n]
:将第 1
步和第 2
步提取的两个子字符串进行拼接,即将原字符串 s