A.整理字符串

解题思路:
多次遍历数组,将前后字符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;
}
}
};

B.找出第 N 个二进制字符串中的第 K 位

解题思路:
模拟。每次长度变为原来的两倍+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];
}
};

C.和为目标值的最大数目不重叠非空子数组数目

解题思路:
先计算出数组的前缀和,对于第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;
}
};

D.切棍子的最小成本

解题思路:
区间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。