LeetCode复建记

想来自己已经几年没碰算法了,连新建博客的按键都找不到。因此在这危急时刻试着刷几道题找找感觉。
简单类可能不想写就跳了,剩下都尽量写一写,如果方便也记录一下时间。

目前做了 8 题!

57. 插入区间 困难 22分钟

饿啊,怎么就花了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;
    }
};

面试题31. 栈的压入、弹出序列 中等 22分钟

思考了十分钟,觉得枚举所有入栈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;
    }
};

400. 第N个数字 中等 14分钟

经典题目,先定位它是几位数,然后定位这个数是几,算就完事了。

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;
    }
};

695. 岛屿的最大面积 中等 8分钟

遍历题,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;
    }
};

304. 二维区域和检索 - 矩阵不可变 中等 7分钟

前缀和,注意矩阵为空可能引发的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);
 */

407. 接雨水 II 困难 49分钟

找了道困难做做,我还是太小看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<heightMap.size();i++)
                {
                    if(vis[i][0]==false&&heightMap[i][0]<=h)
                    {
                        temp+=;
                    }
                    if(vis[i][heightMap[0].size()-1]==false&&heightMap[i][heightMap[0].size()-1]<=h)
                    {
                        temp+=dfs(i,heightMap[0].size()-1,h,heightMap,vis);
                    }
                }
                for(int j=0;j<heightMap[0].size();j++)
                {
                    if(vis[0][j]==false&&heightMap[0][j]<=h)
                    {
                        temp+=dfs(0,j,h,heightMap,vis);
                    }
                    if(vis[heightMap.size()-1][j]==false&&heightMap[heightMap.size()-1][j]<=h)
                    {
                        temp+=dfs(heightMap.size()-1,j,h,heightMap,vis);
                    }
                }
                */
            }
            ans+=cnt-temp;
        }
        return ans;
    }
};

673. 最长递增子序列的个数 中等 8分钟

摸了太久了明天就要面试了啊——
普通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;
    }
};

面试题 04.08. 首个共同祖先 中等 9分钟

连爹也没有的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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值