class Solution {
public:
int diagonalSum(vector<vector<int>>& mat) {
int sum = 0, n = mat.size();
for(int i=0;i<n;i++){
sum += mat[i][i];
if(i!=n-i-1) sum += mat[i][n-i-1];
}
return sum;
}
};
5492. 分割字符串的方案数
几种特殊情况
- 全为0,返回(n-2)*(n-1)/2;
- 1的个数不为3的倍数,返回0;
- 1的个数为3的倍数。乘法原理,计算三段字符串中的中间的0的个数。
class Solution {
public:
int mod = 1e9+7;
int numWays(string s) {
int num = 0, len = s.size();
for(char c:s) if(c=='1') num++;
if(num%3) return 0;
if(num==0){
if(len<3) return 0;
else return (long long)(len-2)%mod*(len-1)/2%mod;
}
int t = num/3, cnt = 0;
int x1,x2,x3,x4;
for(int i=0;i<len;i++){
if(s[i]=='1'){
++ cnt;
if(cnt==t) x1 = i;
if(cnt==t+1) x2 = i;
if(cnt==2*t) x3 = i;
if(cnt==2*t+1) x4 = i;
}
}
return (long long)(x2-x1)%mod*(x4-x3)%mod;
}
};
别人的更加简洁的代码。
typedef long long ll;
class Solution {
public:
int a[100002], P=1000000007;
int numWays(string s) {
int n = s.size(),x=0,y=0;
for(int i = 0; i < n; i++){
a[i+1] = a[i] + (s[i] == '1'); // a[i]表示i之前1的个数
}
if(a[n] == 0) return (ll)(n-1)*(n-2)/2%P; // a[n]为1总数,如果没有1则C(2,n-1)
if(a[n]%3) return 0; // 有1但不满足均分3组
for(int i = 0; i <= n; i++){
if(a[i] == a[n]/3) x++; // 统计第一个分界线可以插入的槽位
if(a[i] == a[n]/3*2) y++; // 统计第二个分解线可以插入的槽位
}
return (ll)x*y%P;
}
};
5493. 删除最短的子数组使剩余数组有序
思路:
首先求出左右两端的升序端。
然后答案可以是只删除两端,取较小值。
最后问题就处理成了,两个有序段,去除第一段的后半部分,去除第二段的前半部分,拼接成一个尽可能长的段。
双指针处理。
class Solution {
public:
int findLengthOfShortestSubarray(vector<int>& a) {
int n = a.size(), l = 1, r = n-1;
while(l<n && a[l]>=a[l-1]) l++;
while(r>0 && a[r]>=a[r-1]) r--;
// [0,l-1] [r,n] 都是升序的
if(l==n) return 0;
int ans = min(n-l,r), i = 0, j = r;
while(i<l && j<n){
// [i+1,j-1]是要删去的
if(a[i]<=a[j]){
ans = min(ans,j-i-1);
i++;
}else j++;
}
return ans;
}
};
/*
[1,2,4,6,8,9,10]
[5,7,9,10,12]
*/
5494. 统计所有可行路径
DP,记忆化搜索实现。
- 状态: d p [ i ] [ f ] dp[i][f] dp[i][f]到达 i i i的时候,油量为 f f f的方案数。
- 状态转移:对所有可以转移的下一个点进行转移,
d
p
[
i
]
[
f
]
=
∑
{
d
p
[
j
]
[
f
−
a
b
s
(
a
[
i
]
−
a
[
j
]
)
]
}
dp[i][f]=\sum \{ dp[j][f-abs(a[i]-a[j])]\}
dp[i][f]=∑{dp[j][f−abs(a[i]−a[j])]}
注意,如果达到某个点的时候,那个点就已经是终点,那么方案数要初始化为1。
class Solution {
public:
int dp[110][210];
int mod = 1e9+7, e , n;
int countRoutes(vector<int>& a, int s, int e, int f) {
this->e = e, n = a.size();
memset(dp,-1,sizeof(dp));
return dfs(s,f,a);
}
int dfs(int i,int f,const vector<int>& a){
if(dp[i][f]!=-1) return dp[i][f];
int &res = dp[i][f];
res = 0;
if(i==e) res = 1;
for(int j=0;j<n;j++){
if(j!=i && abs(a[i]-a[j])<=f){
res = (res+dfs(j,f-abs(a[i]-a[j]),a) )%mod;
}
}
return res;
}
};