代码随想录算法训练营第八天 | LeetCode151.翻转字符串里的单词、卡码网55.右旋转字符串、LeetCode28.实现strStr()、LeetCode459.重复的子字符串

代码随想录算法训练营第八天 | LeetCode151.翻转字符串里的单词、卡码网55.右旋转字符串、LeetCode28.实现strStr()、LeetCode459.重复的子字符串

01-1 字符串总结
题型关键理念
反转字符串首尾指针
反转字符串IIfor循环一段一段处理
替换数字预先给数组扩容带填充后的大小,然后在从后向前进行操作
翻转字符串中的单词整体翻转再局部翻转、前后指针删除空格
左旋、右旋字符串整体翻转再局部翻转
strStr()、重复的子字符串KMP

ref:字符串总结

01-2 双指针回顾

ref:双指针总结

02-1 LeetCode151.翻转字符串里的单词

相关资源

题目:

给你一个字符串 s ,请你反转字符串中单词的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的单词分隔开。

返回单词顺序颠倒且单词之间用单个空格连接的结果字符串。

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

进阶:如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的原地解法。

第一想法:用split函数分割单词,然后定义一个新的string字符串,最后将分割的单词倒叙相加,复杂度极高,一点都不像算法题,遂直接看录哥讲解。

看完代码随想录之后的想法: 本题分为三步走,第一步把字符串先颠倒;第二步通过双指针删除空格;第三步把每个子字符串颠倒!何其壮哉!

实现:

class Solution {
public:
    void reverse(string& s, int start, int end) {
        for (int i = start, j = end; i < j; i++, j--) {
            swap(s[i], s[j]);
        }
    }
    void removeExtraSpaces(string& s) {
        int slow = 0;
        for (int fast = 0;fast < s.size();fast++) {
            if (s[fast] != ' ') {
                if (slow != 0) {
                    s[slow] = ' ';
                    slow = slow + 1;
                }
                while (fast < s.size() && s[fast] != ' ') {
                    s[slow] = s[fast];
                    slow++;
                    fast++;
                }
            }
        }
        s.resize(slow);
    }
    string reverseWords(string s) {
        removeExtraSpaces(s);
        reverse(s, 0, s.size() - 1);
        int start = 0;
        for (int i = 0;i <= s.size();i++) {
            if (i == s.size() || s[i] == ' ') {
                reverse(s, start, i - 1);
                start = i + 1;
            }
        }
        return s;
    }
};

收获:双指针删除字符串空格->复杂度O(n)、翻转字符串里的单词可整体翻转再各个单词翻转

ToDo:复刻录哥的写法

02-2 卡码网55.右旋转字符串

相关资源

题目:

题目描述

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。

例如,对于输入字符串 “abcdefg” 和整数 2,函数应该将其转换为 “fgabcde”。

输入描述

输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。

输出描述

输出共一行,为进行了右旋转操作后的字符串。

输入示例

2
abcdefg

输出示例

fgabcde

提示信息

数据范围:
1 <= k < 10000,
1 <= s.length < 10000;

第一想法:只有一个思路就是提取后k个字符然后再拼接成一个新的字符串,但这样哪有算法的感觉,遂看讲解:不能申请额外空间,只能在本串上操作,我已经无计可施!

看完代码随想录之后的想法:字符串的旋转问题可转化为整体翻转+子串颠倒

实现:

#include<iostream>
#include<algorithm>
using namespace std;
int main() {
	int k;
	string s;
	cin >> k;
	cin >> s;
	int len = s.size();
	reverse(s.begin(), s.end());
	reverse(s.begin(), s.begin() + k);
	reverse(s.begin() + k, s.end());
	cout << s << endl;
}

ToDo:复习

02-3 LeetCode28.实现strStr()

相关资源

  • 题目链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/

  • 文章讲解:实现strStr

  • 视频讲解:理论篇代码篇

看完代码随想录之后的想法: 先pass,因为很难理解

02-4 LeetCode459.重复的子字符串

相关资源

看完代码随想录之后的想法: 先pass!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值