2024.1.11力扣每日一题——构造有效字符串的最少插入数

2024.1.11

      • 题目来源
      • 我的题解
        • [方法一 暴力模拟](#方法一 暴力模拟)
        • [方法二 动态规划](#方法二 动态规划)
        • [方法三 直接拼接](#方法三 直接拼接)
        • [方法四 计算组数](#方法四 计算组数)

题目来源

力扣每日一题;题序:2645

我的题解

方法一 暴力模拟

直接模拟,根据题意可知 若是abc则不用插入,若是ab,ac,bc这需要 插入一个字符,其他的则需要插入两个字符。因此使用String的替换功能,先将word中的所有abc替换成 _ ,然后再分别将ab,ac,bc从左到右替换成 _ ,最后统计剩下的字符中 a b c的数量
时间复杂度 :O( n 2 n^2 n2) n是字符串的长度。除了遍历的O(n),还有替换方法内部的O(n)
空间复杂度:O(1)

java 复制代码
public int addMinimum(String word) {
   word=word.replaceAll("abc","_");
    int n=word.length();
    if(n==0)
        return 0;
    int res=0;
    while(word.contains("ab")){
        res++;
        word=word.replaceFirst("ab","_");
    }
    while(word.contains("bc")){
        res++;
        word=word.replaceFirst("bc","_");
    }
    while(word.contains("ac")){
        res++;
        word=word.replaceFirst("ac","_");
    }
    for(int i=0;i<word.length();i++){
        char ch=word.charAt(i);
        if(ch>='a'&&ch<='c'){
            res+=2;
        }
    }
    return res;
}
方法二 动态规划

定义dp[i]状态表示前i个字符凑成若干个abc所需插入的字符数,则转移过程:

  • 若第i个字符单独在一组abc中,则dp[i]=dp[i-1]+2
  • 若word[i]>word[i-1]则表示word[i]和word[i-1]在一组abc中,则dp[i]=dp[i-1]-1
    时间复杂度:O(n)

空间复杂度:O(n)

java 复制代码
public int addMinimum(String word) {
  int n=word.length();
  int[] dp=new int[n+1];
   for(int i=0;i<n;i++){
       dp[i+1]=dp[i]+2;
       if(i<n-1&&word.charAt(i+1)>word.charAt(i)){
           dp[i+1]=dp[i]-1;
       }
   }
   return dp[n];
}

当然,可以发现转移至于i-1状态有关,所以可以使用滚动数组优化空间

java 复制代码
public int addMinimum(String word) {
    int n=word.length();
    int dp_0=0;
    int dp_1=0;
    for(int i=0;i<n;i++){
        dp_1=dp_0+2;
        if(i<n-1&&word.charAt(i+1)>word.charAt(i)){
            dp_1=dp_0-1;
        }
        dp_0=dp_1;
    }
    return dp_1;
}
方法三 直接拼接

参考:官方题解

当前字符小于等于前面字符说明它们一定不在同一组 abc 中,只需要添置若干字符过渡这两者即可。例如 b前面是 c,则需要在中间添置 a,又例如 b 前面是 b,则需要在中间添置 ca。

以上两种情况可以用一个模型来表示,设当前字符是 x,前面字符是 y,那么需要添置的字符个数为 (x−y−1+3)mod  3。其中 +3 再对 3取模,可以应对 x 小于等于 y 的情况。

最后还需要处理头尾两个字符,word[0] 前面添置 word[0]−'a′ 个字符,word[n−1]后面添置 'c′−word[n−1]个字符。两个可以合并为 word[0]−word[n−1]+2
时间复杂度:O(n)

空间复杂度:O(1)

java 复制代码
 public int addMinimum(String word) {
   int n=word.length();
    int res=0;
    if(n==1)
        return 2;
    res+=word.charAt(0)-word.charAt(n-1)+2;
    for(int i=0;i<n-1;i++){
        int count=word.charAt(i+1)-word.charAt(i)-1+3;
        res+=count%3;
    }
    return res;
  
}
方法四 计算组数

计算递增序列的组------也就是每一个递增序列都是一个组,然后使用一个变量count记录当前递增序列的长度,需要插入的字符数=3-count。在不满足递增的时候才会计算需要插入的字符数,并且重置count。
时间复杂度:O(n)。n是word的长度

空间复杂度:O(1)

java 复制代码
public int addMinimum(String word) {
    int n=word.length();
    if(n==1){
        return 2;
    }
    int res=0;
    int count=1;
    for(int i=0;i<n-1;i++){
        if(word.charAt(i+1)<=word.charAt(i)){
            res+=3-count;
            count=1;
        }else{
            count++;
        }
    }
    return res+(3-count);
  
}

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

相关推荐
白宇横流学长9 分钟前
基于SpringBoot实现的大创管理系统设计与实现【源码+文档】
java·spring boot·后端
fat house cat_37 分钟前
【redis】线程IO模型
java·redis
嘉陵妹妹1 小时前
深度优先算法学习
学习·算法·深度优先
GalaxyPokemon1 小时前
LeetCode - 53. 最大子数组和
算法·leetcode·职场和发展
stein_java2 小时前
springMVC-10验证及国际化
java·spring
weixin_478689762 小时前
C++ 对 C 的兼容性
java·c语言·c++
hn小菜鸡2 小时前
LeetCode 1356.根据数字二进制下1的数目排序
数据结构·算法·leetcode
zhuiQiuMX2 小时前
分享今天做的力扣SQL题
sql·算法·leetcode
LUCIAZZZ2 小时前
HikariCP数据库连接池原理解析
java·jvm·数据库·spring·springboot·线程池·连接池
sky_ph2 小时前
JAVA-GC浅析(二)G1(Garbage First)回收器
java·后端