代码随想录刷题-字符串-反转字符串 II

反转字符串 II

本节对应代码随想录中:代码随想录,讲解视频:字符串操作进阶! | LeetCode:541. 反转字符串II_哔哩哔哩_bilibili

习题

题目链接:541. 反转字符串 II - 力扣(LeetCode)

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

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

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

我的解法

非最优,仅为个人记录

虽然也通过了,但是写的比官方题解麻烦了点,不过还是记录下吧。

题目意思为每2k 个字符反转前 k 个字符,那可以用两个指针 left 和 right 表示每次反转的左右边界,而且每反转一次,left 和 right 都要加上2k,以跳到下一个反转区间。而不满2k 的倍数时剩下的部分也要反转一次,所以总的反转次数为 size / (2 * k) + 1,刚好是2k 的倍数时,会多一次反转,不过只反转的最后一个字符,相当于还是没有改变。同时,left 和 right 每次跳2k,当 right 跳到 size 外面时,让 right=size 解决剩余字符少于 k 时全部反转的问题。

class Solution {
   public:
    string reverseStr(string s, int k) {
        int size = s.length();
        // 如果长度小于等于k则反转s并返回
        if(size <=k){
            reverse(s.begin(),s.end());
            return s;
        }
        int left = 0, right = k; // 每次反转的左右边界
        int nums = size / (2 * k) + 1; // 反转次数
        for (int i = 0; i < nums; i++) {
            reverse(s.begin() + left, s.begin() + right);
            left += 2 * k;
            right += 2 * k;
            // 如果右边界大于数组长度,则让right等于size,以反转剩下的字符
            if (right > size) {
                right = size;
            }
        }
        return s;
    }
};
  • 时间复杂度:O( n n n)。循环次数最多为n/(2k) + 1,因此总的时间复杂度为O(n)
  • 空间复杂度:O( 1 1 1)。只用到了常量级别的额外空间,只需要几个变量存储临时值,因此空间复杂度为 O(1)

LeetCode 官方题解

我的解法中 for 循环只是重复反转次数个循环,而 LeetCode 的解法中 i 每次+=2k。区别于一般所用的 i++,这题每2k 是一个循环,所以用 i+=2k 来计算循环次数。每次循环 i 处于反转区间的左边界,那右边界就是 i+k。不过如果剩余字符小于 k 要将剩余的全部反转,当出现这种情况时,i+k 是在 size 的右边的,也只需要让右边界改为 size 即可。所以每次的右边界就是 min(i+k,size)

class Solution {
public:
    string reverseStr(string s, int k) {
        int size = s.length();
        for (int i = 0; i < size; i += 2 * k) {
            reverse(s.begin() + i, s.begin() + min(i + k, size));
        }
        return s;
    }
};
  • 时间复杂度:O( n n n)。其中 n 为输入字符串的长度,循环次数最多为 n/(2k),因此总的时间复杂度为 O(n)
  • 空间复杂度:O( 1 1 1)。只用到了常量级别的额外空间,只需要几个变量存储临时值,因此空间复杂度为 O(1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值