LeetCode 344. 反转字符串
题目链接:344. 反转字符串
思路:双指针法,比较简单的一道题。
Python版本:
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
l, r = 0, len(s)-1
while l<=r:
s[l],s[r] = s[r],s[l]
l += 1
r -= 1
时间复杂度: O ( n ) O(n) O(n), 空间复杂度: O ( 1 ) O(1) O(1)
go版本:
func reverseString(s []byte) {
l, r := 0, len(s)-1
for l<=r {
s[l], s[r] = s[r], s[l]
l++
r--
}
}
LeetCode 541. 反转字符串 II
题目链接:541. 反转字符串 II
思路:和上一题思路类似,只是多了一个细节,就是每次需要判断一下 i + k i+k i+k是否越界,i每次移动的步长是2k。
Python代码:
class Solution:
def reverseStr(self, s: str, k: int) -> str:
def reverseS(s):
l, r = 0, len(s)-1
while l<r:
s[l],s[r] = s[r],s[l]
l += 1
r -= 1
return s
ss = list(s)
i = 0
while i < len(ss):
if i+k <= len(ss):
ss[i:i+k] = reverseS(ss[i:i+k])
else:
ss[i:] = reverseS(ss[i:])
i += 2*k
return ''.join(ss)
时间复杂度: O ( n ) O(n) O(n), 空间复杂度: O ( n ) O(n) O(n)
go版本:
func reverseStr(s string, k int) string {
ss := []byte(s)
n := len(s)
for i := 0; i < n; i += 2 * k {
if i + k <= n {
reverse(ss[i:i+k])
} else {
reverse(ss[i:])
}
}
return string(ss)
}
func reverse(b []byte) {
l := 0
r := len(b) - 1
for l < r {
b[l], b[r] = b[r], b[l]
l++
r--
}
}
LeetCode 剑指 Offer 05. 替换空格
题目链接:剑指 Offer 05. 替换空格
思路:正常的字符串操作,这里使用了一个列表来存放结果。
Python版本:
class Solution:
def replaceSpace(self, s: str) -> str:
ss = list(s)
res = []
for i in range(len(s)):
if s[i]==' ':
res.append("%20")
else:
res.append(s[i])
return ''.join(res)
时间复杂度: O ( n ) O(n) O(n), 空间复杂度: O ( n ) O(n) O(n)
go版本:
func replaceSpace(s string) string {
ss := []byte(s)
res := make([]byte, 0)
for i:=0; i<len(s); i++ {
if ss[i]==' ' {
res = append(res, []byte("%20")...)
} else {
res = append(res, ss[i])
}
}
return string(res)
}
LeetCode 151. 反转字符串中的单词
题目链接:151. 反转字符串中的单词
思路:观察题目描述和示例,发现需要反转的是单词在句子中的位置,单词自身的字母是不需要反转的,从而通过空格符来作为单词的分隔判断。可以使用Python双端队列支持从队列头部插入的方法,直接按顺序处理单词,然后将单词压入队列的首部。
Python版本:
class Solution:
def reverseWords(self, s: str) -> str:
def foo(ss):
p = 0
while p < len(ss) and ss[p] == " ":
p += 1
return ss[p:]
s = foo(s)
s = foo(s[::-1])[::-1]
res, word = collections.deque(), []
left, right = 0, len(s) - 1
while left <= right:
if s[left] == ' ' and word:
res.appendleft(''.join(word))
word = []
elif s[left] != ' ':
word.append(s[left])
left += 1
res.appendleft(''.join(word))
return ' '.join(res)
时间复杂度: O ( n ) O(n) O(n), 空间复杂度: O ( n ) O(n) O(n)
go版本:
func reverseWords(s string) string {
//1.使用双指针删除冗余的空格
slowIndex, fastIndex := 0, 0
b := []byte(s)
//删除头部冗余空格
for len(b) > 0 && fastIndex < len(b) && b[fastIndex] == ' ' {
fastIndex++
}
//删除单词间冗余空格
for ; fastIndex < len(b); fastIndex++ {
if fastIndex-1 > 0 && b[fastIndex-1] == b[fastIndex] && b[fastIndex] == ' ' {
continue
}
b[slowIndex] = b[fastIndex]
slowIndex++
}
//删除尾部冗余空格
if slowIndex-1 > 0 && b[slowIndex-1] == ' ' {
b = b[:slowIndex-1]
} else {
b = b[:slowIndex]
}
//2.反转整个字符串
reverse(&b, 0, len(b)-1)
//3.反转单个单词 i单词开始位置,j单词结束位置
i := 0
for i < len(b) {
j := i
for ; j < len(b) && b[j] != ' '; j++ {
}
reverse(&b, i, j-1)
i = j
i++
}
return string(b)
}
func reverse(b *[]byte, left, right int) {
for left < right {
(*b)[left], (*b)[right] = (*b)[right], (*b)[left]
left++
right--
}
}
顺着代码随想录的思路,看了几遍代码,自己捋着思路实现了一下。
LeetCode 剑指 Offer 58 - II. 左旋转字符串
思路:较简单,使用了一个辅助数组。如果 不使用辅助数组的话,可以借鉴本篇博客第一题和第二题的思路:先翻转n位之前的字母,再翻转n位到最后一位的字母,然后再翻转一遍字符串。
Python版本:
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
res = []
for i in range(n, len(s)):
res.append(s[i])
for i in range(n):
res.append(s[i])
return ''.join(res)
时间复杂度: O ( n ) O(n) O(n), 空间复杂度: O ( n ) O(n) O(n)
go版本:
func reverseLeftWords(s string, n int) string {
res := make([]byte, 0)
for i:=n; i<len(s); i++ {
res = append(res, s[i])
}
for i:=0; i<n; i++ {
res = append(res, s[i])
}
return string(res)
}
go版本(不使用辅助数组):
func reverseLeftWords(s string, n int) string {
ss := []byte(s)
reverseS(ss[n:])
reverseS(ss[0:n])
reverseS(ss)
return string(ss)
}
func reverseS(s []byte) {
l, r := 0, len(s)-1
for l<=r {
s[l], s[r] = s[r], s[l]
l++
r--
}
}