解题思路:
多次遍历数组,将前后字符ASCII码差值为32的两个字符删除,直到本次遍历没有改变数组。
代码展示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public: string makeGood(string s) { if(s.size()==0 || s.size()==1) return s; int i=0; while(1){ bool tmp=false; for(int i=0;i<s.size()-1;){ if(fabs(s[i]-s[i+1])==32){ tmp=true; if(i==0 && s.size()==2) return ""; else s.erase(i,2); }else i++; } if(!tmp) return s; } } };
|
解题思路:
模拟。每次长度变为原来的两倍+1。
代码展示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: char s[2000000]; char findKthBit(int n, int k) { s[1]='0'; int t = 1; for(int i=2;i<=n;i++){ s[t+1]='1'; for(int j=1;j<=t;j++){ if(s[j] == '0') s[j+t+1] = '1'; else s[j+t+1] = '0'; } int n_t = t*2 +1; for(int j=0;j<(n_t - t-2)/2;j++){ swap(s[t+2+j],s[n_t-j]); } t = n_t; } return s[k]; } };
|
解题思路:
先计算出数组的前缀和,对于第i个前缀和从0~
i-1的前缀和找到是否有tmp = sum[i]-target。如果找到sum[j] = tmp,则找到区间j+1~
i的区间和为target。(区间不重叠问题)最后将所有满足的区间,按右端点从小到大排序,按序选择不重叠的区间,返回区间数。
代码展示:
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
| bool cmp(pair<int,int> x,pair<int,int> y){ if(x.second != y.second) return x.second < y.second; else return x.first<y.first; } class Solution { public: vector<int> sum; vector< pair<int,int> > seg; map<int,int> q; int maxNonOverlapping(vector<int>& nums, int target) { int n = nums.size(); if(n==0) return 0; sum.resize(n); sum[0] = nums[0]; for(int i=1;i<n;i++){ sum[i] = nums[i]+sum[i-1]; } for(int i=0;i<n;i++){ int tmp = sum[i] -target; if(q[tmp]>0){ seg.push_back({q[tmp],i}); }else if(!tmp){ seg.push_back({0,i}); } q[sum[i]] = i+1; } int nseg = seg.size(); sort(seg.begin(),seg.end(),cmp); int ans=0,n_r=-1; for(int i=0;i<nseg;i++){ int l = seg[i].first; if(l>n_r){ ans++; n_r = seg[i].second; } } return ans; } };
|
解题思路:
区间DP,预处理前缀和。dp[i] [j] 表示在当前待切割的木棍的左端点为 cuts[i−1],右端点为 cuts[j] 时,将木棍全部切开的最小总成本。dp[i] [j] = min(dp[i] [j],dp[i] [k]+dp[k+1] [j]+sum[j]-sum[i-1])
代码展示:
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
| class Solution { public: int minCost(int n, vector<int>& cuts) { sort(cuts.begin(),cuts.end()); vector<int> len_ele; len_ele.push_back(0); len_ele.push_back(cuts[0]); for(int i=1;i<cuts.size();i++) len_ele.push_back(cuts[i]-cuts[i-1]); len_ele.push_back(n-cuts[cuts.size()-1]); n = len_ele.size()-1; vector<int> sum(n+1,0); for(int i = 1;i<=n;i++) sum[i] = sum[i-1] + len_ele[i]; vector<vector<int>> dp(n+2,vector<int>(n+2,0)); for(int len = 1;len<n ;len ++){ for(int i=1;i+len<=n;i++){ int j = i+len; dp[i][j] = INT_MAX; for(int k=i;k+1<=j;k++){ dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]); } } } return dp[1][n]; } };
|
做题情况:
AC 三题
排名:674 / 5614
总结反思:
排名很差,比赛中第四题并没有成功AC,归结于之前没怎么写过区间DP。