《最长连续交替01子串问题》| 豆包MarsCode AI刷题

177 阅读4分钟

今天我们将在豆包MarsCode AI刷题平台上,完成《最长连续交替01子串问题》这个算法问题,通过练习提升用户解决此类问题的能力;开始之前先插播一条最新消息:

号外号外📢:豆包MarsCode AI刷题平台已正式上线C++判题功能😮,以后C++选手就不用把程序转为Python或Java形式再提交了🤩并且提交后的反馈界面也调整的更加正式了

提交处:

图片.png

反馈界面:

图片.png

《最长连续交替01子串问题》题面如下:

图片.png

问题理解

题目要求找到通过任意次数的操作后,能够得到的最长的连续交替01子串的长度。这里的操作是将字符串分为两部分,分别翻转后再拼接。

解题思路

  1. 关键理解

    • 直接翻转字符串的某些部分可能会导致复杂的组合,但我们可以通过观察发现,最长的连续交替01子串的长度实际上可以通过直接扫描字符串来确定。
    • 我们用一个字符串s="abcdefg"举例说明:
      • 在下标3和4之间操作:s1="dcbagfe"
      • 在下标2和3之间操作:s2="bcdefga"
      • 在下标4和5之间操作:s3="fedcbag"
      • 在下标1和2之间操作:s4="efgabcd"
      • 在下标5和6之间操作:s5="cbagfed"
    • 这时候很明显就可以发现:不论操作的位置和次数,每次操作之后的字符串sn都可以通过对s的一次操作得到(偶数次操作需要将两段子字符串位置调换,但是不影响最终计算结果)
  2. 核心思路

    • 扫描字符串:通过一次遍历,记录当前连续交替01子串的长度,并在遇到不连续的情况时重置计数。
    • 考虑首尾连接:如果字符串的首尾字符不同,那么可以将首尾的交替子串拼接起来,形成一个更长的交替子串。

代码实现步骤

  1. 初始化变量

    • ret:用于记录最长的交替子串长度。
    • preMaxLength:用于记录以当前字符结尾的最长交替子串长度。
    • firstBeginMax:用于记录由字符串开头开始的最长交替子串长度。
    • endBeginMax:用于记录由字符串结尾开始的最长交替子串长度。
  2. 第一次遍历

    • 由第二个字符开始,检查当前字符与前一个字符是否不同。
    • 如果不同,增加preMaxLength;如果相同,重置preMaxLength为1。
    • 更新retpreMaxLengthret中的较大值。
  3. 第二次遍历

    • 由第二个字符开始,检查当前字符与前一个字符是否不同,直到遇到不连续的字符为止,记录firstBeginMax
    • 由倒数第二个字符开始,检查当前字符与后一个字符是否不同,直到遇到不连续的字符为止,记录endBeginMax
  4. 考虑首尾连接

    • 如果字符串的首尾字符不同,更新retfirstBeginMax + endBeginMaxret中的较大值。

具体实现

class Main {
    public static int solution(String s) {
        int n = s.length();
        if(n == 0) {
            return 0;
        }
        int ret = 1;
        int preMaxLength = 1;
        int firstBeginMax = 1, endBeginMax = 1;
        
        // 第一次遍历,计算以当前字符结尾的最长交替子串长度
        for (int i = 1; i < n; i++) {
            if (s.charAt(i - 1) != s.charAt(i)) {
                preMaxLength++;
            } else {
                preMaxLength = 1;
            }
            ret = Math.max(ret, preMaxLength);
        }
        
        // 第二次遍历,计算由字符串开头开始的最长交替子串长度
        for (int i = 1; i < n; i++) {
            if (s.charAt(i - 1) != s.charAt(i)) {
                firstBeginMax++;
            } else {
                break;
            }
        }
        
        // 第三次遍历,计算由字符串结尾开始的最长交替子串长度
        for (int i = n - 2; i >= 0; i--) {
            if (s.charAt(i + 1) != s.charAt(i)) {
                endBeginMax++;
            } else {
                break;
            }
        }
        
        // 如果首尾字符不同,考虑拼接首尾交替子串
        if (s.charAt(0) != s.charAt(n - 1)) {
            ret = Math.max(ret, firstBeginMax + endBeginMax);
        }
        
        return ret;
    }

    public static void main(String[] args) {
        System.out.println(solution("10010") == 5);
        System.out.println(solution("011010") == 4);
        System.out.println(solution("1010101") == 7);
        System.out.println(solution("11001100") == 2);
        System.out.println(solution("111") == 1);
    }
}
  • 时间复杂度:O(n),其中n是字符串的长度。

  • 空间复杂度:O(1),只使用了常数级别的额外空间。

借助豆包MarsCode AI刷题平台,我们不仅高效地解决了《最长连续交替01子串问题》,还加深了对相关算法和数据结构的理解,后续会借助豆包MarsCode AI给大家展示更多题目的解法