LeetCode.541 反转字符串 II

689 阅读2分钟

这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战

题目描述:

541. 反转字符串 II - 力扣(LeetCode) (leetcode-cn.com)

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

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

示例 1:

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

示例 2:

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

提示:

  • 1<=s.length<=1041 <= s.length <= 10^4
  • s 仅由小写英文组成
  • 1<=k<=1041 <= k <= 10^4

思路分析

模拟

我们直接按题意进行模拟:

反转每个下标从 2k 的倍数开始的长度为 k 的子串。也就是 0, 2k, 4k, 6k ...

若该子串长度不足 k,则反转整个子串。

反转整个字符串我们之前已经做过,正好拿来用。

AC代码

class Solution {
    fun reverseStr(s: String, k: Int): String {
        val ch = s.toCharArray()
        var start = 0

        while (start < s.length) {
            // 每个块开始于 2k 的倍数,也就是 0, 2k, 4k, 6k ...
            val i = start

            // 如果剩余字符少于 k 个,则将剩余字符全部反转。--> j = s.length - 1
            // 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,类同常规情况。--> j = start + k - 1
            val j = Math.min(s.length - 1, start + k - 1)

            // 交换
            swap(i, j, ch)

            // 直接翻转每个 2k 字符块
            start += 2 * k
        }
        
        return String(ch)
    }

    fun swap(i1: Int, j1 : Int, s: CharArray) {
        var i = i1
        var j = j1
        while (i < j) {
            s[i] = s[j].also { s[j] = s[i] }
            i++
            j--
        }
    }

}

总结

总体来说和之前的反转字符串 差不多,字符串相关的题目也做了一些了,常见的就是双指针法之类的,KMP的接下来会集中刷几题做一下。

参考

反转字符串 II - 反转字符串 II - 力扣(LeetCode) (leetcode-cn.com)

【宫水三叶】简单字符串模拟 - 反转字符串 II - 力扣(LeetCode) (leetcode-cn.com)

541. 反转字符串 II - 反转字符串 II - 力扣(LeetCode) (leetcode-cn.com)