class Solution {
public:
bool containsPattern(vector<int>& a, int m, int k) {
int n = a.size();
for(int i=0;i+m*k-1<n;i++){
bool f = true;
for(int j=0;j<m*k;j++){
if(a[i+j] != a[i+j%m] ){
f = false;
break;
}
}
if(f) return true;
}
return false;
}
};
5500. 乘积为正数的最长子数组长度
和之前周赛的一道题目思想很像,只需关心负数出现的次数的奇偶性。由前缀和的思想,
用mp[0]、mp[1]
记录负数出现次数为偶数的最小下标,负数出现次数为奇数的最小下标。
注意0的时候,状态需要全部重置。
class Solution {
public:
int INF = 2e5;
int getMaxLen(vector<int>& a) {
int p = 0, ans = 0;
int mp[2] = {
-1,INF};
for(int i=0;i<a.size();i++){
if(a[i]==0){
mp[0] = i;
mp[1] = INF;
p = 0; //不要忘记更新
continue;
}
if(a[i]<0){
p ^=1;
if(mp[p]==INF) mp[p] = i; // 保留下标最小的
}
ans = max(ans,i-mp[p]);
}
return ans;
}
};
5501. 使陆地分离的最少天数
最重要的思路:结果只可能是0、1、2;
然后写一个判断函数去判断网格图是否是分离的。
const int dx[] = {
-1,0,1,0};
const int dy[] = {
0,1,0,-1};
class Solution {
public:
int m,n;
int minDays(vector<vector<int>>& g) {
m = g.size();
n = g[0].size();
if(check(g)) return 0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(g[i][j]){
g[i][j] = 0;
if(check(g)) return 1;
g[i][j] = 1;
}
}
}
return 2;
}
bool check(const vector<vector<int>>& g) {
int color[40][40] = {
0}, x = -1, y = -1;
bool f = false;
for(int i=0;i<m;i++){
if(f) break;
for(int j=0;j<n;j++){
if(g[i][j]){
x = i, y = j;
dfs(color,x,y,g);
f = !f;
break;
}
}
}
// 全都是0
if(x==-1) return true;
// 有两座岛屿
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(g[i][j]==1 && color[i][j]==0) return true;
}
}
return false;
}
void dfs(int (*color)[40],int x,int y,const vector<vector<int>>& g) {
color[x][y] = 1;
for(int k=0;k<4;k++){
int nx = x+dx[k];
int ny = y+dy[k];
if(nx>=0 && nx<m && ny>=0 && ny<n){
if(g[nx][ny]==1 && !color[nx][ny])
dfs(color,nx,ny,g);
}
}
}
};
5502. 将子数组重新排序得到同一个二叉查找树的方案数
果然涉及到二叉树的十之八九涉及到递归。
其次这道题目需要用递推法求组合数,中间注意mod。
具体的思路:
树根必须选择第一个数,其次类似拓扑排序的概念,有些点必须在另外一些点之前先选,除此之外可以任意交叉。
首先一个组合数确定左子树和右子树的相对关系,然后一棵树的点的插入顺序是相对有序的,注意都是乘法关系。
class Solution {
public:
typedef long long ll;
static const int mod = 1e9+7;
vector<vector<int>> C;
void getC(int n){
for(int i=0;i<=n;i++){
for(int j=0;j<=i;j++){
if(j==0) C[i][j] = 1;
else C[i][j] = (ll)(C[i-1][j-1]+C[i-1][j])%mod;
}
}
}
int numOfWays(vector<int>& nums) {
int n = nums.size();
C.resize(n+2,vector<int>(n+2,0));
getC(n);
return ((f(nums)-1)%mod+mod)%mod;
}
int f(const vector<int> &nums) {
if(nums.empty()) return 1;
int n = nums.size() ,res = 1;
vector<int> lc,rc;
for(int i=1;i<n;i++){
if(nums[i]<nums[0]) lc.push_back(nums[i]);
else rc.push_back(nums[i]);
}
return (ll)C[n-1][lc.size()]*f(lc)%mod*f(rc)%mod;
}
};