代码随想录算法训练营第八天 | 344. 反转字符串、541. 反转字符串 II、剑指05 、151. 反转字符串中的单词、剑指 58

102 阅读3分钟

344. 反转字符串

代码随想录视频讲解

代码随想录文章讲解

左右指针交换

# Time complexity: O(N)
# Space complexity: O(1)
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

使用库函数reverse()

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        s.reverse()

递归

  • 和双指针一样,但是使用递归完成遍历
# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        def helper(l, r):
            if l<r:
                s[l],s[r] = s[r],s[l]
                helper(l+1, r-1)
        
        helper(0, len(s)-1)

541. 反转字符串 II

代码随想录视频讲解

代码随想录文章讲解

将字符转换为list再遍历

  • 每隔 2k 个字符的前 k 个字符进行反转
  • 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
  • 剩余字符少于 k 个,则将剩余字符全部反转。
# Time complexity: O(N)
# Space complexity: O(N)
class Solution(object):
    def reverseStr(self, s, k):
        a = list(s)
        for i in range(0, len(a), 2*k):
            a[i:i+k] = reversed(a[i:i+k])
        return "".join(a)

使用自己写的reverseString方法反转

  • 分两类讨论:

    • 剩下的长度>k:反转前k个
    • 剩下的长度<k:反转剩下的全部
# Time complexity: O(N)
# Space complexity: O(N)
class Solution(object):
    def reverseStr(self, s, k):
        def reverseString(s, l, r):
            while l < r:
                s[l], s[r] = s[r], s[l]
                l += 1
                r -= 1
            
        a = list(s)
        for i in range(0, len(a), 2*k):
            l,r = i, i+k-1
            if len(a) - i < k:
                r = len(a) -1
            reverseString(a, l, r)
        return "".join(a)

剑指 Offer 05. 替换空格

代码随想录文章讲解

使用库函数replace()

class Solution:
    def replaceSpace(self, s: str) -> str:
        return s.replace(" ","%20")

转换为list之后遍历修改

# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
    def replaceSpace(self, s: str) -> str:
        a = list(s)
        for i in range(len(a)):
            if a[i] == " ":
                a[i] = "%20"
        return "".join(a)

数空格个数,增长原string,从新尾部和原尾部开始遍历,遇到空格插入“%20”

不适合python,因为python无法修改string

# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
    def replaceSpace(self, s: str) -> str:
        space_count = s.count(' ')
        res = list(s) + [' ']*2*space_count
        r = len(res) - 1
        for l in range(len(s)-1, -1, -1):
            if res[l] != ' ':
                res[r] = res[l]
                r -= 1
            else:
                res[r - 2: r + 1] = '%20'
                r -= 3
        return ''.join(res)

151. 反转字符串中的单词

代码随想录视频讲解

代码随想录文章讲解

左右指针选定单词范围,从后遍历s,使用额外的list记录答案

# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
    def reverseWords(self, s: str) -> str:
        if len(s) == 1:
            return s
        res = []
        l, r = len(s) - 1, len(s) - 1
        while l > 0 and r > 0:
            while s[r] == " ":
                r -= 1
            l = r
            while s[l]!= " " and l >= 0:
                l -= 1
            if s[l+1 : r+1]!="":
                res.append(s[l+1 : r+1])
            r = l
        return " ".join(res)

使用库函数

# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
    def reverseWords(self, s: str) -> str:
        # You can specify the separator, default separator is any whitespace.
        return " ".join(reversed(s.split()))

去空格,整体翻转,单词单独翻转

# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
    def trim_spaces(self, s: str) -> list:
        left, right = 0, len(s) - 1
        # remove leading spaces
        while left <= right and s[left] == ' ':
            left += 1
​
        # remove trailing spaces
        while left <= right and s[right] == ' ':
            right -= 1
​
        # reduce multiple spaces to single one
        output = []
        while left <= right:
            if s[left] != ' ':
                output.append(s[left])
            elif output[-1] != ' ':
                output.append(s[left])
            left += 1
​
        return output
​
    def reverse(self, l, left, right):
        while left < right:
            l[left], l[right] = l[right], l[left]
            left, right = left+1, right-1
​
    def reverse_each_word(self, l):
        start = end = 0
        while start < len(l):
            while end < len(l) and l[end] != ' ':
                end += 1
            self.reverse(l, start, end-1)
            start = end + 1
            end += 1
​
    def reverseWords(self, s: str) -> str:
        # You can specify the separator, default separator is any whitespace.
        new_s = self.trim_spaces(s)
        self.reverse(new_s, 0, len(new_s)-1)
        self.reverse_each_word(new_s)
        return "".join(new_s)

剑指 Offer 58 - II. 左旋转字符串

代码随想录文章讲解

使用切片拼接

# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        first = s[:n]
        last = s[n:]
        return last+first

反转

  • 反转[0,n)的子串
  • 反转[n,len(s))的子串
  • 反转整个s
# Time complexity: O(N)
# Space complexity: O(N) python不允许原地修改string
class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        s = list(s)
        s[0:n] = list(reversed(s[0:n]))
        s[n:] = list(reversed(s[n:]))
        s.reverse()
​
        return "".join(s)