代码随想录第八天|344.反转字符串、541.反转字符串II、剑指Offer05.替换空格、151.反转字符串中的单词、剑指Offer58-II.左旋转字符串

104 阅读2分钟

344. 反转字符串 - 力扣(LeetCode)

1. 文章链接

代码随想录 (programmercarl.com)

2. 看到题目的第一想法

搞个index, 从头遍历到中间位置mid = len(s) >> 1。 如果s长度是偶数,如4,那么4>>1=20~12~3。 如果s长度是奇数,如5, 那么5>>1=(101)>>1=(10)=2, 0~123~4。 可以看到我们的index只需要取值[0,len(s)>>1)即可。 我们要互换的位置是s[index]s[lend(s) - 1 - index]互换。

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        mid = len(s) >> 1
        for index in range(mid):
            tmp_char = s[index]
            s[index] = s[len(s) - 1 - index]
            s[len(s) - 1 - index] = tmp_char
        return s

3. 看完代码随想录之后的想法

s[index], s[len(s) - 1 - index] = s[len(s) - 1 - index], s[index]

更直接地互换。

4. 实现过程中遇到的困难

无。

5. 学习时长

14分钟。

541. 反转字符串 II - 力扣(LeetCode)

1. 文章链接

代码随想录 (programmercarl.com)

2. 看到题目的第一想法

如果是每2k个字符,就反转前k个字符,那我们可以看看有什么规律: [0, k), [k, 2 * k), [2 * k, 3 * k), [3 * k, 4 * k), ...中:

[0, k), [2 * k, 3 * k), ...将被反转。

所以可以看到,反转的应该是 [index * 2 * k, (index * 2 + 1) * k),

其中index in [0, len(s) // (2 * k))

具体反转的区段内,直接使用 344. 反转字符串 中的方法即可。

class Solution:
    def reverseSubStr(self, s_list: list):
        for i in range(len(s_list) >> 1):
            s_list[i], s_list[len(s_list) - 1 - i] = s_list[len(s_list) - 1 - i], s_list[i]
        return s_list
    def reverseStr(self, s: str, k: int) -> str:
        s = list(s)
        for index in range(len(s) // k):
            if index % 2 == 0:
                sub_s = s[index * k: index * k + k]
                sub_s = self.reverseSubStr(sub_s)
                s[index * k: index * k + k] = sub_s
        # 最后剩余字符少于k个的话要反转
        if len(s) % (2 * k) < k:
            begin = (len(s) // (2 * k)) * 2 * k
            sub_s = s[begin :]
            sub_s = self.reverseSubStr(sub_s)
            s[begin :] = sub_s
        return "".join(s)

3. 实现过程中遇到的困难

首先是无法直接通过[index * 2 * k, (index * 2 + 1) * k)反转得到,因为对于一个子串的对应互换元素位置难以通过之前 344. 反转字符串 计算。

另外,如果最后剩下少于k个元素也要做额外的反转。

4. 看完代码随想录之后的想法

res = list(s)

for cur in range(0, len(s), 2 * k):
    res[cur: cur + k] = reverse_substring(res[cur: cur + k])

return ''.join(res)

可以直接用range的方法来做,每2*k个字符就反转res[cur: cur + k]甚至能够解决剩下不够k个字符的问题。

5. 学习时长

1小时。

剑指 Offer 05. 替换空格 - 力扣(LeetCode)

1. 文章链接

代码随想录 (programmercarl.com)

2. 看到题目的第一想法

就是每遇到一个空格,我们就把s[pre_idx: idx]切片出来,然后加入到res_list中,并紧随其后加入一个"%20"字符串。

然后将idx赋值给pre_idx即可记录无空格连续字段。

最后直接返回"".join(res_list)

3. 看完代码随想录之后的想法

没必要做切片,直接一个字符一个字符地append,遇到空格直接append一个字符串"%20"

4. 实现过程中遇到的困难

无。

5. 学习时长

30分钟。

151. 反转字符串中的单词 - 力扣(LeetCode)

1. 文章链接

代码随想录 (programmercarl.com)

2. 看到题目的第一想法

首先我们要想办法去除多余的空格: 单词之间多余的空格,以及句首和句尾多余的空格。 先将slist,然后每碰到一个空格,就把前一个单词截出来,这一点跟上一题我的方法应该没有区别。但是我们同样也要将空格截出来。

将这些字段加入到res_list后,我们做前后的双指针反转。

class Solution:
    def reverseWords(self, s: str) -> str:
        s_list = list(s)
        begin_idx = 0
        for idx in range(len(s_list)):
            if s_list[idx] != ' ':
                begin_idx = idx
                break
        end_idx = len(s_list) - 1
        for idx in range(len(s_list) - 1, -1, -1):
            if s_list[idx] != ' ':
                end_idx = idx
                break
        s_list = s_list[begin_idx: end_idx + 1]
        s = "".join(s_list)

        res_list = []
        pre_idx = 0
        idx = 0
        while idx < len(s_list):
            if s_list[idx] == ' ':
                res_list.append(s[pre_idx: idx])
                for idx2 in range(idx, len(s_list)):
                    if s_list[idx2] != ' ':
                        pre_idx = idx2
                        idx = pre_idx
                        break
            idx += 1
        res_list.append(s[pre_idx:])
        res_res_list = []
        for idx in range(len(res_list) - 1, -1, -1):
            if idx != 0:
                res_res_list.append(res_list[idx])
                res_res_list.append(" ")
            else:
                res_res_list.append(res_list[idx])
        return "".join(res_res_list)
                

3. 看完代码随想录之后的想法

可以只处理非空格字符,当遇到空格就跳过,直到当前字符为非空格时,如果不是首单词,先加个空格,再加整个单词。 然后反转整个字符串,再一个一个单词单独反转。

4. 实现过程中遇到的困难

如何消除空格这一点不如文档简单。

5. 学习时长

1小时。

剑指 Offer 58 - II. 左旋转字符串 - 力扣(LeetCode)

1. 文章链接

代码随想录 (programmercarl.com)

2. 看到题目的第一想法

这个对于python切片来说非常简单:

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

3. 看完代码随想录之后的想法

python版本跟我想的一样,不用反转。

4. 实现过程中遇到的困难

无。

5. 学习时长

3分钟。