算法训练第八天 | 字符串 344.反转字符串、541. 反转字符串II、剑指Offer 05.替换空格、151.翻转字符串里的单词、剑指Offer58-II.左旋转字符串

LeetCode 344.反转字符串

题目链接

344.反转字符串

思路

双指针思想,向中间遍历

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        left = 0
        right = len(s) - 1
        while left < right :
            s[left], s[right] = s[right], s[left]
            left += 1
            right -= 1

反思

两数交换,在不占用其他空间的情况下,可以直接按照代码方式交换

LeetCode 541. 反转字符串II

题目链接

541. 反转字符串II

思路

利用上一题的翻转规则,加上题目规定的翻转规则:

class Solution:
    def reverseStr(self, s: str, k: int) -> str:       
        def reverse(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)
         #对于字符串s = 'abc',如果使用s[0:999] ===> 'abc'。字符串末尾如果超过最大长度,则会返回至字符串最后一个值,这个特性可以避免一些边界条件的处理
        for i in range(0, len(res), 2*k):
            res[i:i+k] = reverse(res[i:i+k])
            
        return "".join(res)

反思

切片的规则导致若超出范围,可以直接默认取到字符串的最后一个位置上,还是很方便的,否则一定要做如下约束(不然会操作空数组):

for i in range(0, len(res), 2*k):
            if i+k<=len(res):
                res[i:i+k] = reverse(res[i:i+k])
                continue
            res[i:len(res)] = reverse(res[i:len(res)])

上面是个伪代码,思路是这样的,但因为用的切片所以实际执行通不过,也就是没超过就正常执行然后结束本次循环,如果超过了就直接翻转剩下的全部元素

LeetCode 剑指Offer 05.替换空格

题目链接

剑指Offer 05.替换空格

思路

python的内置函数:s.replace(" ", "%20")
不用内置函数的写法:

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

反思

通过的话还是比较容易的,主要是让自己清楚一下不用内置函数怎么替换符号吧

LeetCode 151.翻转字符串里的单词

题目链接

151.翻转字符串里的单词

思路

我的思路和344反转字符串的意思是一样的,就是把每个单词看作一个元素就好(注意要去掉前后缀的空格)
(代码如下:)

class Solution:
    def reverseWords(self, s: str) -> str:
        s.strip()
        res = s.split()
        left, right = 0, len(res)-1
        while left < right:
            res[left], res[right] = res[right], res[left]
            left += 1
            right -= 1
        return " ".join(res)

但是用split还是有些犯规,下方是卡哥讲解,分三步:
eg:源字符串为:"the sky is blue "
1、移除多余空格 : “the sky is blue”
2、字符串反转:“eulb si yks eht”
3、单词反转:“blue is sky the”

class Solution:
    #移除空格
    def trim_spaces(self, s):     
        n = len(s)
        left = 0
        right = n-1
        while left <= right and s[left] == ' ':    #去除开头空格
            left += 1
        while left <= right and s[right] == ' ':   #去除结尾空格
            right = right-1
        tmp = []
        while left <= right:                      #去除中间多余的空格
            if s[left] != ' ':
                tmp.append(s[left])
            elif tmp[-1] != ' ':                 #相邻的上一个位置不是空格,把当前读到的空格放进去
                tmp.append(s[left])
                left += 1
        return tmp
    #2.翻转字符数组
    def reverse_string(self, nums, left, right):
        while left < right:
            nums[left], nums[right] = nums[right], nums[left]
            left += 1
            right -= 1
        return None
	    
    #3.翻转每个单词
    def reverse_each_word(self, nums):
        start = 0
        end = 0
        n = len(nums)
        while start < n:
            while end < n and nums[end] != ' ':
                end += 1
            self.reverse_string(nums, start, end-1)
            start = end + 1
            end += 1
        return None

    def reverseWords(self, s: str) -> str:
        l = self.trim_spaces(s)               
        self.reverse_string(l,  0, len(l)-1)  
        self.reverse_each_word(l)             
        return ''.join(l)  

反思

理解一下如果不用.strip()和.split()怎么完成这道题

LeetCode 剑指Offer58-II.左旋转字符串

题目链接

剑指Offer58-II.左旋转字符串

思路

方法一:直接切片

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

方法二:
1、反转区间为前n的子串
2、反转区间为n到末尾的子串
3、反转整个字符串

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)

方法三这个挺新颖的:在不让用切片的情况下可以使用

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        new_s = ''
        for i in range(len(s)):
            j = (i+n)%len(s)
            new_s = new_s + s[j]
        return new_s

反思

字符串练下来基础操作是做各种翻转,重点关注不能使用一些内置函数的情况下怎么手写出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值