题目大意
题目:1653. 使字符串平衡的最少删除次数
题面总结:
给定一个仅包含 ‘a’ 和 ‘b’ 的字符串 s s s ,要求删除最少数量的字符,使得剩余字符串达到“平衡”状态。
平衡状态定义:
不存在下标对 ( i , j ) (i, j) ( i , j ) 使得 i < j i < j i < j 且 s [ i ] = ′ b ′ s[i] = 'b' s [ i ] = ′ b ′ 同时 s [ j ] = ′ a ′ s[j] = 'a' s [ j ] = ′ a ′ 。换言之,平衡后的字符串中,所有的 ‘a’ 必须出现在所有的 ‘b’ 之前(如 "aaa", "bbb", "aaabbb" 均为平衡状态)。
样例解释:
示例 1: s = "aababbab"
方案 A:删除下标 2 和 6 的字符,得到 "aaabbb",删除次数 2。
方案 B:删除下标 3 和 6 的字符,得到 "aabbbb",删除次数 2。
结论: 最少删除次数为 2。
示例 2: s = "bbaaaaabb"
方案:删除前两个 ‘b’,得到 "aaaaabb"。
结论: 最少删除次数为 2。
数据范围:
说白了就是形如AABBB,AABB ,就是A在前B在后这样子 的呃样子才是平衡状态 。
问,把原字符串变成平衡状态 ,需要最少删除 多少个字符?
思路讲解
思路就是切一刀。如何快速计算在这里切一刀,可以得到的收益是多少呢?可以利用前缀,后缀。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : int minimumDeletions (string s) { s.insert (s.begin (),'#' ); ll N=s.size (); vector<ll> pre_a (N+2 ) ,suf_a (N+2 ) ,pre_b (N+2 ) ,suf_b (N+2 ) ; for (int i=1 ;i<=N;++i){ pre_a[i]=pre_a[i-1 ]+(s[i]=='a' ); pre_b[i]=pre_b[i-1 ]+(s[i]=='b' ); } for (int i=N;i>=1 ;--i){ suf_a[i]=suf_a[i+1 ]+(s[i]=='a' ); suf_b[i]=suf_b[i+1 ]+(s[i]=='b' ); } ll ans=INF; for (int i=1 ;i<=N+1 ;++i){ ans=min (ans,pre_b[i-1 ]+suf_a[i]); } return ans; } };
https://leetcode.cn/problems/minimum-deletions-to-make-string-balanced/submissions/697116504
也可以用DP做DP状态设计,就是第 I 位以A结尾还是以B结尾啊,然后进行这个DP状态转移即可。
下面的代码当中,这个零代表以A结尾,一代表以B结尾。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 func minimumDeletions (s string ) int { n := len (s) dp := make ([][]int , 2 ) for i := range dp { dp[i] = make ([]int , n) } if s[0 ] == 'a' { dp[0 ][0 ] = 0 dp[1 ][0 ] = 1 } else { dp[0 ][0 ] = 1 dp[1 ][0 ] = 0 } for i:=1 ;i<n;i++ { if s[i] == 'a' { dp[0 ][i] = dp[0 ][i-1 ] dp[1 ][i] = dp[1 ][i-1 ] + 1 } else { dp[0 ][i] = dp[0 ][i-1 ] + 1 dp[1 ][i] = min( dp[1 ][i-1 ], dp[0 ][i-1 ]) } } return min( dp[0 ][n-1 ], dp[1 ][n-1 ] ) }
AC代码
https://leetcode.cn/problems/minimum-deletions-to-make-string-balanced/submissions/697109197
源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 #define all(vec) vec.begin(),vec.end() #define PB push_back #define PF push_front #define EB emplace_back #define EF emplace_front #define EM emplace #define FI first #define SE second #define pct __builtin_popcountll #define ctz __builtin_ctzll #define lson(o) (o<<1) #define rson(o) (o<<1|1) #define SZ(a) ((long long) a.size()) #define FOR(i, a, b) for (int i = (a); i <= (b); ++i) #define ROF(i, a, b) for (int i = (a); i >= (b); --i) #define debug(var) cerr << #var <<":" <<var<<"\n" ; #define cend cerr<<"\n-----------\n" #define fsp(x) fixed<<setprecision(x) #define minn(vec) *min_element(vec.begin(),vec.end()) #define maxx(vec) *max_element(vec.begin(),vec.end()) #define yyy cout<<"YES\n" #define nnn cout<<"NO\n" using namespace std;using ll = long long ;using ull = unsigned long long ;using DB=double ;using LD=long double ;using CD=complex<double >;static constexpr ll MAXN=(ll)1e6 +10 ,INF=(1ll <<61 )-1 ;static constexpr ll mod=(ll)1e9 +7 ; static constexpr double eps=1e-8 ;const double pi=acos (-1.0 );class Solution {public : int minimumDeletions (string s) { s.insert (s.begin (),'#' ); ll N=s.size (); vector<ll> pre_a (N+2 ) ,suf_a (N+2 ) ,pre_b (N+2 ) ,suf_b (N+2 ) ; for (int i=1 ;i<=N;++i){ pre_a[i]=pre_a[i-1 ]+(s[i]=='a' ); pre_b[i]=pre_b[i-1 ]+(s[i]=='b' ); } for (int i=N;i>=1 ;--i){ suf_a[i]=suf_a[i+1 ]+(s[i]=='a' ); suf_b[i]=suf_b[i+1 ]+(s[i]=='b' ); } ll ans=INF; for (int i=1 ;i<=N+1 ;++i){ ans=min (ans,pre_b[i-1 ]+suf_a[i]); } return ans; } };
https://leetcode.cn/problems/minimum-deletions-to-make-string-balanced/submissions/697116504
父亲的DP做法代码,go语言
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 func minimumDeletions (s string ) int { n := len (s) dp := make ([][]int , 2 ) for i := range dp { dp[i] = make ([]int , n) } if s[0 ] == 'a' { dp[0 ][0 ] = 0 dp[1 ][0 ] = 1 } else { dp[0 ][0 ] = 1 dp[1 ][0 ] = 0 } for i:=1 ;i<n;i++ { if s[i] == 'a' { dp[0 ][i] = dp[0 ][i-1 ] dp[1 ][i] = dp[1 ][i-1 ] + 1 } else { dp[0 ][i] = dp[0 ][i-1 ] + 1 dp[1 ][i] = min( dp[1 ][i-1 ], dp[0 ][i-1 ]) } } return min( dp[0 ][n-1 ], dp[1 ][n-1 ] ) }
心路历程(WA,TLE,MLE……)