列表

详情


NC187. 压缩字符串(二)

描述

利用字符重复出现的次数,编写一种方法,最多可以先删掉k个字符,再实现字符串压缩,返回压缩过后字符串的最小长度。比如,字符串aabcccccaaa,k=0时,会压缩变为a2bc5a3,返回7。
1.如果只有一个字符,1不用写
2.新增一个先删除k个字符的处理,也可以不删除,也可以删除少于k个字符,要达到压缩过后字符串的长度为最小
3.字符串中只包含大小写英文字母(a至z)

数据范围:
0<=字符串长度<=100
0<=k<=字符串长度

示例1

输入:

"aabcccccaaa",0

输出:

7

说明:

压缩后的字符串为"a2bc5a3",长度为7

示例2

输入:

"aabcccccaaa",1

输出:

6

说明:

在不删除任何任何字符串时候,压缩后的字符串为"a2bc5a3",删除1个字符串b之后,压缩后的字符串最好为"a2c5a3",长度为6,删除其他的字符,长度依然为7

示例3

输入:

"aaabbbaaa",3

输出:

2

说明:

删除3个b字符,压缩后为a6,长度为2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 3ms, 内存消耗: 396KB, 提交时间: 2022-01-14

#include<vector>
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param k int整型 
     * @return int整型
     */
    int compressString(string s, int k) {
        // write code here
        int lens = s.length();
        vector<vector<int>>dp(lens+1,vector<int>(k+1,INT_MAX>>1));//存储前i个字符串中删除掉j个后最短长度
        dp[0][0] = 0;
        for(int i = 0;i<=lens;i++){
            for(int j = 0;j<=i&&j<=k;j++){
                if(j>0)
                    dp[i][j] = dp[i-1][j-1];//删掉第i个字符
                int same = 0,diff = 0;
                for(int f = i;f >=1&&diff<=j;f--){//如果字符相同,考虑是否保留
                    if(s[i-1] == s[f-1])
                        dp[i][j] = min(dp[i][j],dp[f-1][j-diff]+zip(++same));
                    else
                        diff++;
                }
            }
        }
        return dp[lens][k];
    }
    int zip(int n){
        if(n==1) return 1;
        if(n<10) return 2;
        if(n<100) return 3;
        return 4;
    }
};

C++ 解法, 执行用时: 3ms, 内存消耗: 408KB, 提交时间: 2021-12-09

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串
     * @param k int整型
     * @return int整型
     */
    int compressString(string s, int k) {
        auto calc = [](int x) {
            if (x == 1) {
                return 1;
            }
            if (x < 10) {
                return 2;
            }
            if (x < 100) {
                return 3;
            }
            return 4;
        };
  
        int n = s.size();
        vector<vector<int>> f(n + 1, vector<int>(k + 1, INT_MAX >> 1));
        f[0][0] = 0;
        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j <= k && j <= i; ++j) {
                if (j > 0) {
                    f[i][j] = f[i - 1][j - 1];
                }
                int same = 0, diff = 0;
                for (int i0 = i; i0 >= 1 && diff <= j; --i0) {
                    if (s[i0 - 1] == s[i - 1]) {
                        ++same;
                        f[i][j] = min(f[i][j], f[i0 - 1][j - diff] + calc(same));
                    } else {
                        ++diff;
                    }
                }
            }
        }
  
        return f[n][k];
    }
};

C 解法, 执行用时: 3ms, 内存消耗: 412KB, 提交时间: 2022-06-06

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param s string字符串 
 * @param k int整型 
 * @return int整型
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
int min(int a, int b) {
    return a > b ? b : a;
}
int max(int a, int b) {
    return a > b ? a : b;
}
int count(int k) {
    if (k <= 1) return 0;
    if (k < 10) return 1;
    if (k < 100) return 2;
    return 3;
}
int compressString(char* s, int k) {
    int sLen = strlen(s);
    if (s == NULL || k >= sLen) {
        return 0;
    }
    
    int **dp = (int **)malloc(sizeof(int *) * (sLen + 1));
    for (int i = 0; i < sLen + 1; i++) {
        dp[i] = (int *)malloc(sizeof(int) * (k + 1));
        for (int j = 0; j < k + 1; j++) {
            dp[i][j] = max(0, i-j);
        }
    }
    
    int del = 0, l = 0, sameCount = 0;
    
    for (int i = 1; i < sLen + 1; i++) {
        dp[i][0] = i;
        for (int j = 0; j <= i && j < k + 1; j++) {
            if (j > 0) {
                dp[i][j] = min(dp[i-1][j-1], dp[i-1][j] + 1);
            }
            
            del = 0;
            sameCount = 0;
            for (l = i; l > 0; l--) {
                if (s[l-1] == s[i-1]) {
                    sameCount++;
                } else {
                    dp[i][j] = min(dp[l][j-del] + count(sameCount) + 1, dp[i][j]);
                    
                    if (++del > j) {
                        break;
                    }
                }
            }
            if (l == 0) {
                dp[i][j] = min(count(sameCount) + 1, dp[i][j]);
            }
        }
    } 
    
    int result = dp[sLen][k];
    
    for (int i = 0; i < sLen + 1; i++) {
        free(dp[i]);
    }
    free(dp);
    
    return result;
}




C++ 解法, 执行用时: 3ms, 内存消耗: 448KB, 提交时间: 2021-12-16

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param k int整型 
     * @return int整型
     */
    int compressString(string s, int k) {
        if (s.size() == 0) {
            return 0;
        }
        vector<vector<int>> line(s.size(), vector<int>(k+1,0));
        int letter = s[0];
        int count = 1;
        line[0][0] = 1;
        for (int i = 1; i < s.size(); i++) {
            line[i][0] = line[i - 1][0];
            if (s[i] == letter) {
                count++;
                if (count == 2 ||count == 10 || count == 100) {
                    line[i][0] += 1;
                }
            } else {
                letter = s[i];
                count = 1;
                line[i][0] += 1;
            }
        }
        
        
        auto it = s.begin();
        for (int total = 1; total< s.size(); total ++) {
            int letter = s[total];
            int size = min(total, k);
            for (int i = 1; i <= size; i++) {
                // 删除当前字母的情况
                line[total][i] = line[total-1][i-1];
                // 删除的数量
                int del =0;
                int same = 0;
                count = 1;
                // 不删除当前字母,则把该字母往前匹配,尽量找出相同的字母,删除不同的字母,找出最优解
                for (int j = total; j >=0; j --) {
                    int letterJ = s[j];
                    if (letterJ == letter) {
                        same ++;
                        if (same == 2) {
                            count = 2;
                        } else if ( same == 10) {
                            count = 3;
                        } else if (same == 100) {
                            count = 4;
                        }
                        if (j == 0) {
                            line[total][i] = min(line[total][i], count);
                        } else {
                            line[total][i] = min(line[total][i], line[j - 1][i - del] + count);
                        }
                        
                    } else {
                        del ++;
                        if (del > i) {
                            break;
                        }
                         if (j == 0) {
                            line[total][i] = min(line[total][i], count);
                        } else {
                            line[total][i] = min(line[total][i], line[j - 1][i - del] + count);
                        }
                    }
                }
            }
            
        }
        return line[s.size()-1][k];
    }
    
    

};

C++ 解法, 执行用时: 3ms, 内存消耗: 512KB, 提交时间: 2021-11-27

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串
     * @param k int整型
     * @return int整型
     */
    int compressString(string s, int k) {
        auto calc = [](int x) {
            if (x == 1) {
                return 1;
            }
            if (x < 10) {
                return 2;
            }
            if (x < 100) {
                return 3;
            }
            return 4;
        };
 
        int n = s.size();
        vector<vector<int>> f(n + 1, vector<int>(k + 1, INT_MAX >> 1));
        f[0][0] = 0;
        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j <= k && j <= i; ++j) {
                if (j > 0) {
                    f[i][j] = f[i - 1][j - 1];
                }
                int same = 0, diff = 0;
                for (int i0 = i; i0 >= 1 && diff <= j; --i0) {
                    if (s[i0 - 1] == s[i - 1]) {
                        ++same;
                        f[i][j] = min(f[i][j], f[i0 - 1][j - diff] + calc(same));
                    } else {
                        ++diff;
                    }
                }
            }
        }
 
        return f[n][k];
    }
};

上一题