代码随想录算法训练营No8 |LeetCode344.反转字符串541. 反转字符串II 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转

字符串1


今天开始字符串。

344.反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

这题很简单,可以使用库函数reverse,也可以使用双指针。
本题使用双指针。

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

        return s

541. 反转字符串II
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

思考了一会儿,决定用for循环来控制2k字符,然后对2k个字符进行前k个反转操作。

class Solution:
    def reverseStr(self, s: str, k: int) -> str:
        def reversestr(s):
            left, right = 0, len(s) - 1
            while left < right:
                s[left], s[right] = s[right], s[left]
                left += 1
                right -= 1
            return s
        res = list(s)  # 我错在这个地方,没有把string转化为list,再来交换赋值
        for i in range(0,len(res),2*k):
                res[i:i+k] = reversestr(res[i:i+k])
        return ''.join(res)

本题思路出来了,代码也写对了,就是没有把str转化为list再来进行交换赋值操作,导致错误。

剑指Offer 05.替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

class Solution:
    def replaceSpace(self, s: str) -> str:
        s = list(s)
        for i in range(len(s)):
            if s[i] ==" ":
                s[i] = "%20"

        return ''.join(s)
class Solution:
    def replaceSpace(self, s: str) -> str:
        return '%20'.join(s.split(' '))

快慢指针

class Solution:
    def replaceSpace(self, s: str) -> str:
        counter = s.count(' ')
        res = list(s)
        res.extend([' '] * counter * 2) #’%20‘占3个位置

        #i指向新列表的尾部,j指向原始列表的尾部
        #i总是慢于j,或者和j速度一致
        i ,j = len(res)-1 , len(s) - 1
        while j >= 0:
            if res[j] != ' ':
                res[i] = res[j]
                i -= 1
            else:
                res[i-2:i+1] = '%20' #左闭右开
                i -= 3
            j -= 1
        return ''.join(res)

151.翻转字符串里的单词
给你一个字符串 s ,请你反转字符串中单词的顺序。
单词是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回单词顺序颠倒且单词之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

解题思路:

  • 移除多余空格
  • 将整个字符串反转
  • 将每个单词反转
class Solution:
    def reverseWords(self, s: str) -> str:
        # 移除多余空格
        l ,r = 0 ,len(s)-1
        while l <= r and s[l] == ' ':
            l += 1
        while l <= r and s[r] == ' ':
            r -= 1
        temp = []
        for i in range(l,r+1):
            if s[i] != ' ':
                temp.append(s[i])
            elif s[i-1] != ' ':
                temp.append(s[i])
                
        # 反转字符串  写成函数,下面还用到
        def reverse_w(s,l,r):
            while l <= r:
                temp[l] , temp[r] = temp[r] , temp[l]
                l += 1
                r -= 1
            return None

        reverse_w(temp,0,len(temp) - 1)
        # 反转单词
        start ,end = 0 , 0
        n = len(temp)
        while start < n:
            while end < n and temp[end] != ' ':
                end += 1
            reverse_w(temp,start,end-1)
            start = end +1
            end += 1

        return ''.join(temp)

解法2:

class Solution:
    def reverseWords(self, s: str) -> str:
        # method 1 - Rude but work & efficient method.
        s_list = [i for i in s.split(" ") if len(i) > 0]
        return " ".join(s_list[::-1])

58-II.左旋转
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        return s[n:]+s[0:n]

不用字符串切片
具体步骤为:

  • 反转区间为前n的子串
  • 反转区间为n到末尾的子串
  • 反转整个字符串
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)

不用reversed库函数

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        # 局部反转函数
        def resvered_part(temp,l,r):
            while l <= r:
                temp[l] ,temp[r] = temp[r] ,temp[l]
                l += 1
                r -= 1
                
        s = list(s) #python中string为不可变类型,所以不能直接赋值,需要转化为list再赋值
        resvered_part(s,0,n-1)
        resvered_part(s,n,len(s)-1)
        resvered_part(s,0,len(s)-1)

        return ''.join(s)

今天本来以为挺简单,实际花费了4个多小时,主要是python中string是不可变类型,无法单独赋值,还有一些string的基本操作不熟练,耗费了时间,整体做下来,思路还算清晰,同为字符串的题,使用方法也不尽相同,需要结合题干要求,具体考虑最优方案。

你可能感兴趣的:(---数据结构与算法---,#,python语言描述,#,Leetcode,leetcode,字符串,双指针)