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);
  
}

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

相关推荐
Eloudy3 分钟前
简明量子态密度矩阵理论知识点总结
算法·量子力学
点云SLAM4 分钟前
Eigen 中矩阵的拼接(Concatenation)与 分块(Block Access)操作使用详解和示例演示
人工智能·线性代数·算法·矩阵·eigen数学工具库·矩阵分块操作·矩阵拼接操作
Warren9837 分钟前
Java Stream流的使用
java·开发语言·windows·spring boot·后端·python·硬件工程
算法_小学生2 小时前
支持向量机(SVM)完整解析:原理 + 推导 + 核方法 + 实战
算法·机器学习·支持向量机
架构师沉默2 小时前
Java优雅使用Spring Boot+MQTT推送与订阅
java·开发语言·spring boot
tuokuac2 小时前
MyBatis 与 Spring Boot版本匹配问题
java·spring boot·mybatis
iamlujingtao2 小时前
js多边形算法:获取多边形中心点,且必定在多边形内部
javascript·算法
算法_小学生2 小时前
逻辑回归(Logistic Regression)详解:从原理到实战一站式掌握
算法·机器学习·逻辑回归
zhysunny3 小时前
05.原型模式:从影分身术到细胞分裂的编程艺术
java·原型模式
DebugKitty3 小时前
C语言14-指针4-二维数组传参、指针数组传参、viod*指针
c语言·开发语言·算法·指针传参·void指针·数组指针传参