Day16(字符串start)

💫坚持真的很难,希望自己不要松懈啊。


📆学习日期:2025年2月7日23:03:23

💻学习内容:反转字符串 | 代码随想录 反转字符串II | 代码随想录

⏲️学习时长:1h25min

练习题目1-反转字符串
题目描述

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

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

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

示例 2:

输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

提示:

  • 1 <= s.length <= 105
  • s[i] 都是 ASCII 码表中的可打印字符
解题思路
  • 整体思路&&注意事项
  1. 字符串和数组的算法思路基本差不多
  2. 本题为 双指针法 的经典应用

  • 代码实现
  1. 使用两个指针进行头尾元素的交换
  2. 指针i指向头部,指针j指向尾部,两个元素交换,指针逐步向中间移动
  3. 边界条件:“代入法”

例如奇数 s = ["h","e","l","l","o"],len=5, i<len/2,即i=0,1 其中2不需要交换,偶数 s = ["h","e","l","l"] i<len/2,即i=0,1,两个交换也成立,因此条件为 i<len/2(而不是i<=len/2)

  • for(i=0,j=len-1;i<len/2;i++,j--)
  • j的边界条件不需要,因为ij是同时移动的
  1. 使用swap()函数进行元素交换
  • 什么时候可以使用库函数:库函数直接解决题目,则不要使用,库函数是实现的一部分,可以使用。

Bug

class Solution {
public:
    void reverseString(vector<char>& s) {
        int len=s.size();//字符串长度
        
        for(int i=0,j=len-1;i<len/2;i++,j--){
            char temp=s[i];//交换  //使用库函数 swap(s[i],s[j]),是同款操作
            s[i]=s[j];
            s[j]=temp;
        }
        
        
    }
};
练习题目2-反转字符串II
题目描述

设置标签 541. 反转字符串 II - 力扣(LeetCode)

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

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

示例 1:

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

示例 2:

输入:s = "abcd", k = 2
输出:"bacd"

提示:

  • 1 <= s.length <= 104
  • s 仅由小写英文组成
  • 1 <= k <= 104
解题思路
  • 整体思路&&注意事项
  1. 模拟此复杂规则之下的反转,没有其他的算法
  2. 与 反转字符串 是一脉相承的,使用到了 反转字符串 的操作
  3. 遍历字符串的for循环不一定写i++, 以2k为一个操作单位进行遍历,i+=2k
  • 代码实现
  1. for(i=0;i<s.size();i+=2k)//对字符串要进行一段一段的操作
  2. 需要操作的是前k个字符

if(i+k<=s.size());需要凑够k个可以操作的数//注意边界条件

reverse(s,i,i+k);//这里使用了库函数,可以借鉴上一题反转字符串的操作

  1. 尾部不足k个字符的操作:

将剩余的字符全部反转 reverse(s,i,s.size());

Bug

reverse(s,i,s.size());这个是伪代码的形式,真实的reverse函数不是这样的

class Solution {
public:
    //自定义my_reverse函数
    //void() my_reverse()

    string reverseStr(string s, int k) {
        for(int i=0;i<s.size();i+=2*k){//i以2k为单位遍历字符串,相当于计数了
            
            if(i+k<=s.size()){//以2k为单位跳,最后这段需要凑够k个
                reverse(s.begin()+i,s.begin()+i+k);
                //continue;//进入下一个2k,没搞懂这个continue,用if-else也可以
            }

            //尾部没凑够k个
            else reverse(s.begin()+i,s.end());
        }

        return s;
        
    }
};
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]);
        }
    }
    string reverseStr(string s, int k) {
        for (int i = 0; i < s.size(); i += (2 * k)) {
            // 1. 每隔 2k 个字符的前 k 个字符进行反转
            // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
            if (i + k <= s.size()) {
                reverse(s, i, i + k - 1);
                continue;
            }
            // 3. 剩余字符少于 k 个,则将剩余字符全部反转。
            reverse(s, i, s.size() - 1);
        }
        return s;
    }
};
class Solution {
public:
    string reverseStr(string s, int k) {
        int n = s.size(),pos = 0;
        while(pos < n){
            //剩余字符串大于等于k的情况
            if(pos + k < n) reverse(s.begin() + pos, s.begin() + pos + k);
            //剩余字符串不足k的情况 
            else reverse(s.begin() + pos,s.end());
            pos += 2 * k;
        }
        return s;
    }
};
学习总结
  1. 双指针的思路 待总结

代码随想录-反转链表

  1. swap()函数 待总结
  2. 分段处理的for循环操作,i的跳数
相关题目

反转字符串中的元音字母 简单

反转字符串 II 简单


反转字符串 简单

反转字符串中的单词 III 简单

故障键盘 简单

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值