直接模拟,根据题意可知 若是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)
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)
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状态有关,所以可以使用滚动数组优化空间
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)
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)
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);
}
有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~