力扣(LeetCode)每日随机一题——2645.构造有效字符串的最少插入数[中等]

一、题目

构造有效字符串的最少插入数

123

二、代码

做出来咯🎉🎉🎉

// 1
class Solution {
    public int addMinimum(String word) {
        // 将字符串转换为字符数组
        // 从前往后对每个字符进行判断-判断是否有效
        // 将字符分为a,b,c三种情况去处理
        int count = 0;
        char c[] = word.toCharArray();
        for(int i=0;i<c.length;i++) {
            // 对每个字符进行处理:分三种情况
            if(c[i]=='a') {
                if(c[i+1]=='b') {
                    if(c[i+2]=='c') {
                        i = i+2;
                    }else {
                        count++;
                        i++;
                    }
                }
            }else if(c[i]=='b') {
                if(c[i+1]=='c') {
                    count++;
                    i++;
                }else {
                    count = count+2;
                }
            }else if(c[i]=='c') {
                count = count+2;
            }
        }
        return count;
    }
}
/**
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
  at line 11, Solution.addMinimum
  at line 54, __DriverSolution__.__helper__
  at line 84, __Driver__.main
*/ 
Kim:从前向后判断字符会出现数组越界问题;于是尝试从后向前遍历字符-但仍会因--操作对在数组下标1附近进行判断时会出现越界情况,因此对处理进行筛选,下标小于c.length-2时进行处理,剩余部分做特殊处理
// 2
class Solution {
    public static int addMinimum(String word) {
        // 将字符串转换为字符数组
        // 从前往后对每个字符进行判断-判断是否有效
        // 将字符分为a,b,c三种情况去处理
        int count = 0;
        char c[] = word.toCharArray();
        // 标记是否在第一步处理中对最后两个元素已处理完
        boolean f1 = false;
        boolean f2 = false;

        for(int i=0;i<c.length-2;i++) {
            // 对小标小于c.length-2的字符进行处理:分三种情况
            if(c[i]=='a') {
                if(c[i+1]=='b') {
                    if(c[i+2]=='c') {
                        // 由于在处理过程中会随时改变i的值,故判断语句应放在最前
                        if(i==c.length-3) {
                            f1 = true;
                        }
                        i = i+2;
                    }else {
                        if(i==c.length-3) {
                            f2 = true;
                        }
                        count++;
//                        System.out.println("a"+count);
                        i++;
                    }
                }else if(c[i+1]=='c') {
                    if(i==c.length-3) {
                        f2 = true;
                    }
                    count++;
//                    System.out.println("b"+count);
                    i++;
                }else {
                    count = count+2;
//                    System.out.println("c"+count);
                }
            }else if(c[i]=='b') {
                if(c[i+1]=='c') {
                    if(i==c.length-3) {
                        f2 = true;
                    }
                    count++;
//                    System.out.println("d"+count);
                    i++;
                }else {
                    count = count+2;
//                    System.out.println("e"+count);
                }
            }else {
                count = count+2;
//                System.out.println("f"+count);
            }
        }
        // 对剩余的最后两个字符进行处理
        int l2 = (c.length)-2;
        int l1 = (c.length)-1;

//        System.out.println(f2);
//        System.out.println(f1);

        if(f2==true && f1==true) {
            return count;
        }else if(f2==true) {
            count = count+2;
//            System.out.println("g"+count);
        }else {
            if(c[l2]=='a') {
                if(c[l1]=='a') {
                    count = count+4;
//                    System.out.println("h"+count);
                }else {
                    count++;
//                    System.out.println("i"+count);
                }
            }else if(c[l2]=='b') {
                if(c[l1]=='c') {
                    count++;
//                    System.out.println("j"+count);
                }else {
                    count = count+4;
//                    System.out.println("k"+count);
                }
            }else {
                count = count+4;
//                System.out.println("l"+count);
            }
        }

        return count;
    }
}
/**
java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 1
  at line 71, Solution.addMinimum
  at line 54, __DriverSolution__.__helper__
  at line 84, __Driver__.main
*/
Kim:在IDEA中执行自己随意设置的两个个测试用例都没有问题,但在官网运行行总会出现数组越界问题,可恶!ʕ◉ᴥ◉ʔ
Kim:最后发现是少了字符长度为12的两种情况才会越界呜呜呜~
Kim:调试过程中还修改了 判断 在第一步处理中对最后两个元素是否已处理完 的逻辑	(第六个测试用例发现)
测试用例:
1."b"
2."aaa"
3."abc"
4."abcaacb"
5."abcaacbcb"
6."aaabca"
// 3
class Solution {
    public static int addMinimum(String word) {
        // 将字符串转换为字符数组
        // 从前往后对每个字符进行判断-判断是否有效
        // 将字符分为a,b,c三种情况去处理
        int count = 0;
        char c[] = word.toCharArray();
        // 标记是否在第一步处理中对最后两个元素已处理完
        boolean f1 = false;
        boolean f2 = false;

        if(c.length==1) {
          return 2;
        } else if(c.length>2) {
            for(int i=0;i<c.length-2;i++) {
                // 对小标小于c.length-2的字符进行处理:分三种情况
                if(c[i]=='a') {
                    if(c[i+1]=='b') {
                        if(c[i+2]=='c') {
                            i = i+2;
                            if(i==c.length-2) {
                                f2 = true;
                            }
                            if(i==c.length-1) {
                                f1 = true;
                            }
                        }else {
                            count++;
//                        System.out.println("a"+count);
                            i++;
                            if(i==c.length-2) {
                                f2 = true;
                            }
                            if(i==c.length-1) {
                                f1 = true;
                            }
                        }
                    }else if(c[i+1]=='c') {
                        count++;
//                    System.out.println("b"+count);
                        i++;
                        if(i==c.length-2) {
                            f2 = true;
                        }
                        if(i==c.length-1) {
                            f1 = true;
                        }
                    }else {
                        count = count+2;
//                    System.out.println("c"+count);
                    }
                }else if(c[i]=='b') {
                    if(c[i+1]=='c') {
                        count++;
//                    System.out.println("d"+count);
                        i++;
                        if(i==c.length-2) {
                            f2 = true;
                        }
                        if(i==c.length-1) {
                            f1 = true;
                        }
                    }else {
                        count = count+2;
//                    System.out.println("e"+count);
                    }
                }else {
                    count = count+2;
//                System.out.println("f"+count);
                }
            }
        }

        // 对剩余的最后两个字符进行处理
        int l2 = (c.length)-2;
        int l1 = (c.length)-1;

//        System.out.println(f2);
//        System.out.println(f1);

        if(f1==true) {
            return count;
        }else if(f2==true) {
            count = count+2;
//            System.out.println("g"+count);
        }else {
            if(c[l2]=='a') {
                if(c[l1]=='a') {
                    count = count+4;
//                    System.out.println("h"+count);
                }else {
                    count++;
//                    System.out.println("i"+count);
                }
            }else if(c[l2]=='b') {
                if(c[l1]=='c') {
                    count++;
//                    System.out.println("j"+count);
                }else {
                    count = count+4;
//                    System.out.println("k"+count);
                }
            }else {
                count = count+4;
//                System.out.println("l"+count);
            }
        }

        return count;
    }
}
Kim:最终修改正确后的代码

三、题解

考虑相邻字母

对于两个相邻字符 x 和 y(x 在 y 左侧),使 s (word记为s)有效的话需要插入 y−x−1abc顺序计算正好各差一位,故若是正确顺序则应为后减前再-1为0,此时不用添加任何字母) 个字母(这里计算的每次都是以当前 i 为下标的字母前需要插入几个字母)。

考虑到这可能是个负数(如:cb,b比c小但在b后,就会出现b-c=-1的情况),可以通过如下技巧转换在[0,2] 内:(y−x−1+3) mod 3 (每两组串联的"abc"之间任意两个字母最多相差2;意思是从相邻两组的每一组中分别任意取出一个字母,这两个字母最大相差2,故对3取模

例如 x=‘a’,y=‘c’,则有 (‘c’−‘a’+2) mod 3=1,意思是需要补一个字母 ‘b’。
例如 x=‘c’,y=‘a’,则有 (‘a’−‘c’+2) mod 3=0,无需补字母。

最后补齐开头的 s[0]−‘a’(由于代码中使用了 i-1 为了防止数组越界,故从下标为1的开始遍历,又由于word首字母一定为a,故只需要计算当前字母与a的差值即可,当前字母一定大于等于a,即需要补上一次判断首字母前需要插入几个字母),和结尾的 ‘c’−s[n−1](**与补齐开头类似,这里需要补上一次判断尾字母后需要插入几个字母【尾字母一定为c,即当前字母一定小于等于c】)。这俩可以合并为s[0]−s[n−1]+2。

/**
题解给出了两种思路,一个为考虑相邻字母另一个为abc的周期数,我选择第一种与自己思路相近的答案进行学习解析
*/
class Solution {

    public int addMinimum(String word) {

        var s = word.toCharArray();

        int ans = s[0] + 2 - s[s.length - 1];

        for (int i = 1; i < s.length; ++i)

            ans += (s[i] + 2 - s[i - 1]) % 3;
            // (s[i] - s[i-1] - 1 + 3)%3

        return ans;

    }

}

作者:力扣官方题解
来源:力扣(LeetCode

四、总结

其他:
java中使用s.toCharArray()将字符串转换成字符数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值