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

文章详细介绍了如何解决LeetCode上的541题,即反转字符串II。作者提供了自己的解法和官方的解法,两种方法都实现了在字符串中按特定步长反转子串的功能。作者的解法使用了两个指针left和right,而官方解法直接用i作为左边界并递增2k。两者的时间和空间复杂度均为O(n)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反转字符串 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)
### 代码随想录中的Python答案 对于希望在《代码随想录》中查找Python的答案,该资源提供了详细的算法目解析以及对应的解决方案。具体到不同类型的目,《代码随想录》不仅提供了解决方案还深入讲解了背后的原理。 针对数组类问,在处理`sortedSquares`函数时采用了一种更高效的方法来解决平方排序的问[^1]: ```python class Solution: def sortedSquares(self, nums: List[int]) -> List[int]: result = [0] * len(nums) # 初始化结果列表 left, right, pos = 0, len(nums) - 1, len(nums) - 1 while left <= right: if abs(nums[left]) > abs(nums[right]): result[pos] = nums[left] ** 2 left += 1 else: result[pos] = nums[right] ** 2 right -= 1 pos -= 1 return result ``` 此方法利用双指针技术有效地减少了不必要的计算开销,并且保持了时间复杂度为O(n),而不需要额外的空间除返回的结果外[^2]。 当涉及到动态规划问初始化时,则依据具体情况决定如何设置初始状态。例如,当面对含有负数值的情况时,非零索引位置应被设为负无穷大以确保后续比较逻辑正确无误[^4]。 另外,《代码随想录》也涵盖了更多高级主如单调栈的应用实例,这有助于理解特定场景下的最优解法[^5]。 #### 注意事项 为了更好地理解和应用这些解答建议读者仔细阅读原文档内的解释说明部分,因为那里包含了实现细节背后的重要概念和技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值