想来自己已经几年没碰算法了,连新建博客的按键都找不到。因此在这危急时刻试着刷几道题找找感觉。
简单类可能不想写就跳了,剩下都尽量写一写,如果方便也记录一下时间。
饿啊,怎么就花了22分钟。
就是一个分类讨论题,细节比较多,vector的一些操作也有些不太熟悉。
顺着找到第一个相交的区间,然后再找最后一个相交的区间就行了。
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
bool flag=true;
for(int i=0;i<intervals.size();i++) {
if(newInterval[0]<=intervals[i][1])
{
flag=false;
if(newInterval[1]<intervals[i][0])
{
intervals.insert(intervals.begin()+i,newInterval);
break;
}
intervals[i][0]=min(intervals[i][0],newInterval[0]);
int j;
for(j=i;j<intervals.size();j++) {
if(intervals[j][0]>newInterval[1])
break;
}
intervals[i][1]=max(max(intervals[i][1],intervals[j-1][1]),newInterval[1]);
intervals.erase(intervals.begin()+i+1,intervals.begin()+j);
break;
}
}
if(flag)
intervals.push_back(newInterval);
return intervals;
}
};
思考了十分钟,觉得枚举所有入栈123出栈312的三元组就行了。
然后调了一会WA了一发就过了,点开题解发现模拟就 O ( N ) O(N) O(N)……
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
//true 123 321 132 213 231
//false 312
vector<int>val2popped(1000,0);
for(int i=0;i<popped.size();i++)
{
val2popped[popped[i]]=i;
}
for(int i=0;i<pushed.size();i++) //2
{
int flag1=-1,flag2=0x3fffffff;
for(int j=0;j<pushed.size();j++)
{
if(j==i)
continue;
if(j<i&&val2popped[pushed[j]]<val2popped[pushed[i]])
flag1=max(val2popped[pushed[j]],flag1);
if(j>i&&val2popped[pushed[j]]<val2popped[pushed[i]])
flag2=min(val2popped[pushed[j]],flag2);
}
if(flag1>flag2){
return false;
}
}
return true;
}
};
经典题目,先定位它是几位数,然后定位这个数是几,算就完事了。
class Solution {
int pow10(int x)
{
if(x==0)
return 1;
return pow10(x-1)*10;
}
public:
int findNthDigit(int n) {
int k;
for(k=1;;k++)
{
if(n>(long long)k*9*pow10(k-1))
n-=k*9*pow10(k-1);
else
break;
}
n--;
int x=n/k;
int y=n-x*k;
int num=pow10(k-1)+x;
// printf("%d %d %d %d\n",n,x,y,num);
return num/pow10(k-1-y)%10;
}
};
遍历题,dps写起来比较顺手。
class Solution {
int dfs(int x,int y,vector<vector<int>>& grid,vector<vector<bool>>& vis)
{
if(x<0||y<0||x>=grid.size()||y>=grid[0].size())
return 0;
if(grid[x][y]==0)
return 0;
if(vis[x][y])
return 0;
vis[x][y]=true;
return 1+dfs(x-1,y,grid,vis)+dfs(x,y-1,grid,vis)+dfs(x+1,y,grid,vis)+dfs(x,y+1,grid,vis);
}
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int ans=0;
vector<vector<bool> >vis;
for(int i=0;i<grid.size();i++)
vis.push_back(vector<bool>(grid[i].size(),false));
for(int i=0;i<grid.size();i++)
{
for(int j=0;j<grid[i].size();j++)
{
if(vis[i][j]==false&&grid[i][j]==1)
{
ans=max(ans,dfs(i,j,grid,vis));
}
}
}
return ans;
}
};
前缀和,注意矩阵为空可能引发的bug。
class NumMatrix {
vector<vector<int>> sum;
public:
NumMatrix(vector<vector<int>>& matrix) {
for(int i=0;i<=matrix.size();i++)
{
sum.push_back(vector<int>(matrix.size()==0?1:matrix[0].size()+1,0));
}
for(int i=0;i<matrix.size();i++)
{
for(int j=0;j<matrix[i].size();j++)
{
sum[i+1][j+1]=sum[i][j+1]+sum[i+1][j]-sum[i][j]+matrix[i][j];
}
}
}
int sumRegion(int row1, int col1, int row2, int col2) {
printf("%d %d %d %d",row1,col1,row2,col2);
return sum[row2+1][col2+1]-sum[row1][col2+1]-sum[row2+1][col1]+sum[row1][col1];
}
};
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix* obj = new NumMatrix(matrix);
* int param_1 = obj->sumRegion(row1,col1,row2,col2);
*/
找了道困难做做,我还是太小看leetcode了。
想法很简单,从最下面往最上面维护会漏水的格子即可,但是不太好的写法会对时间复杂度产生影响。
最开始写了一个 O ( 20000 ( N M ) 2 ) O(20000(NM)^2) O(20000(NM)2),没过,然后搞了个 O ( 20000 + ( N M ) 2 ) O(20000+(NM)^2) O(20000+(NM)2)还是没过,然后改成了 O ( 20000 + N M ) O(20000+NM) O(20000+NM)就过了。深夜不太清醒,不过 1 0 8 10^8 108跑不了的时间限制真的是1秒吗——
vector也太难用了,代码可读性确实没了。
class Solution {
int dfs(int x,int y, int h, vector<vector<int>>& heightMap, vector<vector<bool>>& vis)
{
if(x<0||y<0||x>=heightMap.size()||y>=heightMap[0].size())
return 0;
if(vis[x][y]==true||heightMap[x][y]>h)
return 0;
vis[x][y]=true;
return 1+dfs(x-1,y,h,heightMap,vis)+dfs(x,y-1,h,heightMap,vis)+dfs(x+1,y,h,heightMap,vis)+dfs(x,y+1,h,heightMap,vis);
}
public:
int trapRainWater(vector<vector<int>>& heightMap) {
vector<vector<bool> >vis;
vector<vector<pair<int,int> > >rMap(20002);
for(int i=0;i<heightMap.size();i++)
{
for(int j=0;j<heightMap[0].size();j++)
{
rMap[heightMap[i][j]].push_back(pair<int,int>(i,j));
}
}
int ans=0;
for(int i=0;i<heightMap.size();i++)
{
vis.push_back(vector<bool>(heightMap[0].size(),false));
}
int cnt=0;
int temp=0;
for(int h=0;h<=20001;h++)
{
for(auto p:rMap[h])
{
int i=p.first,j=p.second;
cnt++;
if((i==0||(i>0&&vis[i-1][j]))||(j==0||(j>0&&vis[i][j-1]))||(i==heightMap.size()-1||(i<heightMap.size()-1&&vis[i+1][j]))||(j==heightMap[0].size()-1||(j<heightMap[0].size()-1&&vis[i][j+1])))
temp+=dfs(i,j,h,heightMap,vis);
/*
for(int i=0;i
}
ans+=cnt-temp;
}
return ans;
}
};
摸了太久了明天就要面试了啊——
普通DP题,五分钟写完,f g写反调了两分钟。
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
vector<int>f(nums.size(),1);
vector<int>g(nums.size(),1);
int l=0,ans=0;
for(int i=0;i<nums.size();i++)
{
for(int j=0;j<i;j++)
{
if(nums[i]>nums[j])
{
if(f[j]+1>f[i])
{
f[i]=f[j]+1;
g[i]=g[j];
}
else if(f[j]+1==f[i])
{
g[i]+=g[j];
}
}
}
if(f[i]>l)
{
l=f[i];
ans=g[i];
}
else if(f[i]==l)
{
ans+=g[i];
}
}
return ans;
}
};
连爹也没有的LCA,想法就是dfs找到第一个子树有p和q的节点,用int保存是否拥有的状态返回即可。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int dfs(TreeNode* now, TreeNode* p, TreeNode* q, TreeNode* &ans) {
if(now==NULL)
return 0;
int ret=0;
if(now==p)
ret|=1;
if(now==q)
ret|=2;
ret|=dfs(now->left,p,q,ans);
ret|=dfs(now->right,p,q,ans);
if(ans==NULL&&(ret&3)==3)
ans=now;
return ret;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
TreeNode* ans=NULL;
assert(dfs(root,p,q,ans)==3);
return ans;
}
};