LeetCode 每日一题 541 + 647

120 阅读2分钟

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

541. 反转字符串 II

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

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

示例 1:

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

示例 2:

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

提示:

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

方法一

模拟:

遍历一遍字符串,当前位置i模上k等于0,模上2k不为0,说明是我们要进行反转的尾巴,那么我们对其进行反转;

最后,对字符串进行一个特判,看看字符串最后几个字符是不是小于k

class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        int n = ch.length;
        for (int i = 0; i < n; i ++ ) {
            if ((i + 1) % k == 0 && (i + 1) % (2 * k) != 0) {
                int j = i - k + 1, u = i;
                while (j < u) {
                    char tmp = ch[j];
                    ch[j ++] = ch[u];
                    ch[u --] = tmp;
                }
            }
        }
        int cnt = n % (2 * k);
        if (cnt < k) {
            int i = n - cnt, j = i + cnt - 1;
            while(i < j) {
                char tmp = ch[j];
                ch[j --] = ch[i];
                ch[i ++] = tmp;
            }
        }
        return new String(ch);
    }
}

647. 回文子串

给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:

输入:"abc"
输出:3
解释:三个回文子串: "a", "b", "c"

示例 2:

输入:"aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

提示:

  • 输入的字符串长度不会超过 1000 。

方法一

看到回文串问题,首先想到马拉车,字符串哈希,动态规划;

此题我用动态规划来解:

区间DP,f[i][j]表示以i为头j为尾的字符串能否构成回文串

状态转移:f[i][j] = ch[i]==ch[j] && f[i+1][j-1]

class Solution {
    public int countSubstrings(String s) {
        char[] ch = s.toCharArray();
        int n = ch.length, res = 0;
​
        boolean[][] f = new boolean[n][n];
        for (int len = 1; len <= n; len ++ ) {
            for (int l = 0; l + len - 1 < n; l ++ ) {
                int r = l + len - 1;
                if (len == 1) f[l][l] = true;
                else if (len == 2) {
                    if (ch[l] == ch[r]) f[l][r] = true;
                    else f[l][r] = false;
                }
                else {
                    f[l][r] = f[l + 1][r - 1] && ch[r] == ch[l];
                }
                if (f[l][r]) res ++;
            }
        }
        return res;
    }
}