A.矩阵对角线元素的和
解题思路:
直接暴力,当变长是偶数是不用减最中间的数,当边长是奇数时要减去最中间的数。比赛的时候没想那么多,看不大就用了各数组标记有没有加过。
代码:
class Solution {
public:
int diagonalSum(vector<vector<int>>& mat) {
int ans = 0;
int n = mat.size();
int vis[105][105];
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
if(!vis[i][i])
ans += mat[i][i];
vis[i][i] = 1;
if(!vis[i][n-1-i])
ans += mat[i][n-1-i];
vis[i][n-1-i] = 1;
}
return ans;
}
};
B.分割字符串的方案数
解题思路:
1、当
1
1
1的个数不能被
3
3
3整除时,答案和
0
0
0;
2、当没有
1
1
1时,怎么分都可以,那么就是C(n,2)(n表示字符串长度);
3、否则就是两两分界点直接可以选择的范围相乘;
代码:
class Solution {
public:
int numWays(string s) {
int mod = 1e9+7;
int len = s.size();
int one = 0;
for(int i=0;i<len;i++)
if(s[i] == '1')
one++;
if(one%3)return 0;
if(one == 0)
{
long long ans = (long long)(len-1)*(len-2)/2%mod;
return ans;
}
int l1=-1,l2=-1,r1=-1,r2=-1,cnt=0;
for(int i=0;i<len;i++)
{
if(s[i] == '1')
cnt++;
if(l1 == -1 && cnt == one/3)
l1 = i;
if(r1 == -1 && cnt == one/3+1)
r1 = i;
if(l2 == -1 && cnt == one/3*2)
l2 = i;
if(r2 == -1 && cnt == one/3*2+1)
r2 = i;
}
long long ans = (long long)(r1-l1)*(r2-l2)%mod;
return ans;
}
};
C.删除最短的子数组使剩余数组有序
解题思路:
直接二分答案,当知道了要去除的长度,怎么判断是否可行呢,只要枚举所有去除的起点的位置,接着看下它前面和后面是否递增(前面后面指的是没被删除的),并且前面最后一个是否不大于后面第一个,是否递增预处理即可。
代码:
class Solution {
const int maxn = 1e5+5;
int s1,s2,len;
int ok(int x,vector<int>& a)
{
for(int i=0;i+x<=len;i++)
{
if(i>0 && s1<i-1)continue;
if(i+x<len && s2>i+x)continue;
if(i>0&&i+x<len&&a[i-1]>a[i+x])continue;
return 1;
}
return 0;
}
public:
int findLengthOfShortestSubarray(vector<int>& arr) {
len = arr.size();
s1 = 0;
for(int i=1;i<len;i++)
if(arr[i] >= arr[i-1])
s1 = i;
else
break;
s2 = len-1;
for(int i=len-2;i>=0;i--)
if(arr[i] <= arr[i+1])
s2 = i;
else
break;
int l = 0,r=len;
int ans;
while(l < r)
{
int mid = (l+r)/2;
if(ok(mid,arr))
{
ans = mid;
r = mid;
}
else
l = mid + 1;
}
return ans;
}
};
D.统计所有可行路径
解题思路:
以看就是DP,但是我们可以发现每个点都是可以多次经过的,那么我们不能按常规思路不是线性的,但是发现油只会越来越少,那么我们外层循环可以表示油,设 d p [ i ] [ j ] dp[i][j] dp[i][j]为还剩 i i i的油在点 j j j的总数,开始 d p [ f u e l ] [ s t a r t ] = 1 dp[fuel][start]=1 dp[fuel][start]=1,由于一个点可以从其它任意点过来,所以再枚举来的点,转移比较简单就不写了。
代码:
class Solution {
public:
int countRoutes(vector<int>& locations, int start, int finish, int fuel) {
long long dp[205][105];
int mod = 1e9+7;
int n = locations.size();
memset(dp,0,sizeof(dp));
dp[fuel][start] = 1;
for(int i=fuel;i>0;i--)
{
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
{
if(k == j)continue;
int c = abs(locations[k]-locations[j]);
if(c <= i)
{
dp[i-c][k] += dp[i][j];
dp[i-c][k] %= mod;
}
}
}
}
long long ans = 0;
for(int i=0;i<=fuel;i++)
{
ans += dp[i][finish] ;
ans %= mod;
}
return ans;
}
};