代码随想录 Day 9 | 151.翻转字符串里的单词、卡码网:55.右旋转字符串、28. 实现 strStr()、459.重复的子字符串、字符串总结 、双指针回顾

一、151.翻转字符串里的单词

建议:这道题目基本把 刚刚做过的字符串操作 都覆盖了,不过就算知道解题思路,本题代码并不容易写,要多练一练。

题目链接/文章讲解/视频讲解:代码随想录

1. 看完代码随想录的想法

法1:定义翻转函数+另开新数组+剔除空格+双指针翻转单词       

 总体思路:注意翻转单词和翻转字符并不一样,此处还需要剔除多余空格,保留两两单词之间的唯一空格。首先,可以将整个字符串全部反转一次,然后再将各个单词的字符串进行翻转;其次,使用双指针法进行空格剔除,快指针用于遍历整个字符串,慢指针用于存放不等于空格的字符,并且需要在每个单词之间增加一个空格。

(1)首先定义一个函数single_reverse,用于给定一个字符串以及指定的头和尾,将这个字符串的指定位置进行翻转;

(2)接下来定义主函数:首先另开一个新字符串,用于存放最终结果;定义一个指针初始化指向索引为0处;然后使用list()将给定的字符串强制转化为列表形式,方便进行遍历取值;最后使用reverse库函数将这个字符串列表进行整体全部翻转;

(3)接下来删除多余空格:首先指针遍历整个字符串列表(while fast < len(s):),如果该位置不是空格则进入下一步,如果是空格则指针继续指向下一个位置,直到该位置不是空格;如果该位置不是空格,我们需要添加一个判断,如果这个单词是结果集的第一个单词,那么不需要添加空格,因为第一个单词前面不需要空格;接下来我们需要将这个非空格位置对应的值存放进结果集result中,并且继续向下遍历,直到一个单词全部写入结果集;进入下一个循环后结果集里会添加一个空格,这样就满足了每个单词之间只有一个空格;

(4)最后我们需要调用最开始定义的翻转指定位置的字符串,对每个单词进行翻转;初始化快慢指针均指向0;然后将结果集字符串转化为列表;同样的以空格为界,快指针去遍历整个结果集字符串,遇到空格就判断前为同一单词的字符,并调用函数将其翻转;下一次循环需要将慢指针指向快指针+1处,快指针向后移动一位即可;

(5)最后之间拼接反转后的单词。

class Solution:
    def single_reverse(self, s, start: int, end: int):
        while start < end:
            s[start], s[end] = s[end], s[start]
            start += 1
            end -= 1

    def reverseWords(self, s: str) -> str:
        result = ""
        fast = 0
        # 1. 首先将原字符串反转并且除掉空格, 并且加入到新的字符串当中
        # 由于Python字符串的不可变性,因此只能转换为列表进行处理
        s = list(s)
        s.reverse()
        while fast < len(s):
            if s[fast] != " ":
                if len(result) != 0:
                    result += " "
                while s[fast] != " " and fast < len(s):
                    result += s[fast]
                    fast += 1
            else:
                fast += 1
        # 2.其次将每个单词进行翻转操作
        slow = 0
        fast = 0
        result = list(result)
        while fast <= len(result):
            if fast == len(result) or result[fast] == " ":
                self.single_reverse(result, slow, fast - 1)
                slow = fast + 1
                fast += 1
            else:
                fast += 1

        return "".join(result)

双指针法:

(1)首先使用split函数将字符串拆分成字符串列表,默认为按空格进行拆分;

(2)定义左指针和右指针,分别指向每个字符串列表的头和尾,并将每个单词进行翻转;

(3)最后返回用join函数以空格“ ”进行连接。

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

2、遇到的困难及解决

(1)需要特别注意:空格" "引号里面需要空格,而不是习惯性直接写引号!

(2)split()函数:split函数传入的是字符串,输出的是字符串列表。

二、卡码网:55.右旋转字符串

建议:题解中的解法如果没接触过的话,应该会想不到

题目链接/文章讲解: 右旋转

1. 看到本题的第一想法

        首先使用list函数将字符串转化为字符串列表;然后如果想将倒数第n个元素移动到整个数组的最前面,那么不可避免每次挪动一个元素,都需要使用循环遍历将前面的元素依次向后移动,实现起来非常困难。

2. 看完代码随想录的想法

        首先对字符串数组进行切片,然后再进行拼接。

s=int(input())
k=input()

s=s[len(s)-k:] + s[:len(s)-k]

print(s)

三、28. 实现 strStr()

因为KMP算法很难,大家别奢求 一次就把kmp全理解了,大家刚学KMP一定会有各种各样的疑问,先留着,别期望立刻啃明白,第一遍了解大概思路,二刷的时候,再看KMP会 好懂很多。

或者说大家可以放弃一刷可以不看KMP,今天来回顾一下之前的算法题目就可以。

因为大家 算法能力还没到,细扣 很难的算法,会把自己绕进去,就算别人给解释,只会激发出更多的问题和疑惑。所以大家先了解大体过程,知道这么回事, 等自己有 算法基础和思维了,在看多看几遍视频,慢慢就理解了。

题目链接/文章讲解/视频讲解:代码随想录

本题是KMP 经典题目。以下文字如果看不进去,可以看《代码随想录》算法视频公开课 (opens new window),相信结合视频再看本篇题解,更有助于大家对本题的理解。

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        return haystack.find(needle)

四、459.重复的子字符串

本题算是KMP算法的一个应用,不过 对KMP了解不够熟练的话,理解本题就难很多。

我的建议是 KMP和本题,一刷的时候 ,可以适当放过,了解怎么回事就行,二刷的时候再来硬啃

题目链接/文章讲解/视频讲解:代码随想录

1. 看完代码随想录的想法

        (1)判断输入的字符串长度是否合法,要求非空并且有子串,所以长度必须大于1,否则直接返回False;

        (2)接下来将两个字符串分别去掉头和尾并将它们拼接,如果使用find函数还能在拼接后的字符串找到原始字符串的话,就说明原字符串可以由它的子串反复构成;

        (3)最后返回bool类型的结果,如果可以就返回True,否则返回False。

class Solution:
    def repeatedSubstringPattern(self, s:str) -> bool:
        if len(s) <= 1:
            return False

        ss = s[1:]+s[:-1]
        return ss.find(s)!=-1
       

2. 实现过程中遇到的困难及解决

(1)在定义函数时注意->表示最后返回的结果类型。

(2)find()函数:

五、字符串总结

题目链接/文章讲解: 代码随想录

 1. 字符串定义

字符串就是由多个字符组成的有限序列,也可以理解为字符数组。

2. 是否应该使用库函数

例如substr,split,reverse之类的库函数,如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数;如果库函数仅仅是 解题过程中的一小部分,并且你已经很清楚这个库函数的内部实现原理的话,可以考虑使用库函数。

并且如果调用库函数,需要了解其实现原理以及时间复杂度。

六、双指针总结

此时我们已经做过10道双指针的题目了,总结一下双指针的心得

文章讲解:代码随想录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值