leetcode 实战篇-字符串

前言

哈喽大家好,我是雨墨,小老弟又来了,这是小老弟的第二篇博客,记录小老弟我刷字符串类型的leetcode 题目的笔记。每日更新3道,直至完成目标~
话不多说,咱们开始正题~~
目标已完成,本专题停止更新😁

leetcode 344 反转字符串(开胃菜)

题目链接

传送门:https://leetcode-cn.com/problems/reverse-string/

我的题解

题目描述

编写一个函数,将字符串反转过来,要求必须原地修改字符串。

样例

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

算法

(双指针) O ( n ) O(n) O(n)

算法描述:使用两个指针,一个往后走,一个往前走,交换两个指针所指的元素,直到两个指针相遇,整个字符串就反转过来了。

class Solution {
   
public:
    void reverseString(vector<char>& s) {
   
        int len = s.size();

        for (int head = 0, tail = len - 1; head < tail; ++head, --tail) 
            swap(s[head], s[tail]);
    }
};

leetcode 541 反转字符串Ⅱ(换一个玩法)

题目链接

传送门:https://leetcode-cn.com/problems/reverse-string-ii/

我的题解

题目描述

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

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

样例

输入:s = "abcdefg", k = 2
输出:"bacdfeg"

算法

(模拟) O ( n ) O(n) O(n)

题目要求要在每2k个字符中选择前k个字符反转,那每次i += 2 * k就可以了,再多考虑数组长度满不满足大于 k 的情况就可以了。

class Solution {
   
public:
    string reverseStr(string s, int k) {
   
        int len = s.size();

        for (int i = 0; i < len; i += 2 * k) {
   
            int l = i, r = min(l + k, len);
            reverse(s.begin() + l, s.begin() + r);
        }

        return s;
    }
};

剑指offer 05 替换空格

题目链接

传送门:https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/submissions/

我的题解

题目描述

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

样例

输入:s = "We are happy."
输出:"We%20are%20happy."

算法1

(复制+替换) O ( n ) O(n) O(n)

将原字符串的内容拷贝到新的字符串内,如果遇到 ‘ ’, 就向新的字符串中添加%20。但是这种空间复杂度也是 O ( n ) O(n) O(n)

class Solution {
   
public:
    string replaceSpace(string s) {
   
        int len = s.size();
        string str;

        for (int i = 0; i < len; ++i) {
   
            if (s[i] != ' ')
                str += s[i];
            else str += "%20";
        }

        return str;
    }
};

算法2

(双指针) O ( n ) O(n) O(n)

先计算将空格替换之后新的字符串会变成多大的长度,然后对原字符串resize这个新的长度,一个指针i从原数组的尾部向头走,一个指针j从新的字符串尾部向头走,如果没有遇到空格,则直接s[j--] = s[i],否则将空格转换成%20。这样空间复杂度为 O ( 1 ) O(1) O(1)

class Solution {
      
public:
    string replaceSpace(string s) {
   
        int len = s.size(), new_len = 0;
        for (const auto& str : s) {
   
            if (str == ' ') new_len += 3;
            else new_len ++;
        }

        s.resize(new_len);

        for (int i = len - 1, j = new_len - 1; ~i; --i) {
   
            if (s[i] != ' ') s[j--] = s[i];
            else {
   
                s[j--] = '0';
                s[j--] = '2';
                s[j--] = '%';
            }
        }

        return s;
    }
};

leetcode 151 翻转字符串里的单词(好题,字符串重点题)

题目链接

传送门:https://leetcode-cn.com/problems/reverse-words-in-a-string/

我的题解

题目描述

给定一个字符串,逐个反转所有单词

说明:

  • 输入字符串 s 可以在前面、后面或者单词间包含多余的空格。
  • 翻转后单词间应当仅用一个空格分隔。
  • 翻转后的字符串中不应包含额外的空格。

样例

输入:s = "  hello world  "
输出:"world hello"

算法

(拆分问题) O ( n ) O(n) O(n)

这道题乍一看确实很难想,没办法一步到位,那就只好把这道题拆解逐个击破,这也是一种很重要的思想。

算法描述:

  • 可以先将这个字符串全部反转
  • 然后再逐个反转每个单题且保证每个单题之后以空格间隔,删去不必要的空格
  • 更多实现细节见代码
class Solution {
   
public:
    string reverseWords(string s) {
   
        int len = s.size();
        reverse(s.begin(), s.end());    // 先将整个字符串翻转

        int beg_of_word = 0;    // 每个单词的开头
        for (int slowIndex = 0; slowIndex < len; ++slowIndex) {
   
            if (s[slowIndex] == ' ') continue;  // 找到第一个不是 ' ' 的字符
            int fastIndex = slowIndex, end_of_word = beg_of_word;
            // 寻找每一个完整的单词并用其覆盖原字符串 
            while (s[fastIndex] != ' ' && fastIndex < len) s[end_of_word++] = s[fastIndex++];
            // 翻转每个单词
            reverse(s.begin() + beg_of_word, s.begin() + end_of_word);
            s[end_of_word++] = ' '; // 在每个单词末尾添加 ' '
            beg_of_word = end_of_word, slowIndex = fastIndex;   // 更新
        }
        // 只要出现一个单词,那在其末尾一定会添加一个 ' '
        if (beg_of_word) --beg_of_word; 
        // 将末尾多余的 ' ' 删去
        s.erase(s.begin() + beg_of_word, s.end());

        return s;
    }
};

剑指offer 58 左旋转字符串

题目链接

传送门:https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/

我的题解

题目描述

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

样例

输入: s = "abcdefg", k = 2
输出: "cdefgab"

算法

(思维题) O ( n ) O(n) O(n)

这道题我是把难度调大了的,也就是在 O ( 1 ) O(1) O(1)的空间复杂度下使得字符串左旋转。遇到问题一步不能到位,那就把它拆解,先reverse整个字符串一遍,将后 n 个字符串reverse一遍,再将前面的字符串reverse一遍,即可得到答案。


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值