Leetcode Top 100 Liked Questions(序号53~74)

这篇具有很好参考价值的文章主要介绍了Leetcode Top 100 Liked Questions(序号53~74)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

53. Maximum Subarray 

题意:一个数组,找到和最大的子串

我的思路

我记得好像On的动态规划来做的?但是想不起来了,先死做,用的前缀和——TLE超时

那就只能想想dp怎么做了

假设dp[i]表示的是以 i 为右端点的最大的子串,dp[0]是自己;

i=1时,如果dp[0]小于0,dp[1]=nums[1],否则dp[1]=dp[0]+nums[1]

i=2时,如果dp[1]小于0,dp[2]=nums[2],否则dp[2]=dp[2-1]+nums[2]

所以状态转移方程为:如果dp[i - 1]小于0,dp[ i ]=nums[ i ],否则dp[ i ]=dp[i -1]+nums[ i ]

On解决,同时dp换成nums还能更省空间

代码 Runtime 87 ms Beats 78.76% Memory67.9 MB Beats 8.86%

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n=nums.size();
        int maxx=nums[0];
        for(int i=1;i<n;i++){
            if(nums[i-1]>0) nums[i]=nums[i]+nums[i-1];
            maxx=max(maxx,nums[i]);
        }
        return maxx;
    }
};

如果想跟快的话,取消同步 Runtime 50 ms Beats 99.91% Memory 67.7 MB Beats 81.53%

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);    cout.tie(NULL);
        int n=nums.size();
        int maxx=nums[0];
        for(int i=1;i<n;i++){
            if(nums[i-1]>0) nums[i]=nums[i]+nums[i-1];
            maxx=max(maxx,nums[i]);
        }
        return maxx;
    }
};

标答补充 分治

看看分治的代码

分成左右中三个部分,左边部分是左边最大的子串和,右边部分得到右边最大字串和;

左边部分是所有包含了m-1位置的字符串的最大子串和 lmax,右边部分是包含了m+1位置的字符串的最大字串和 rmax,返回max(lmax. rmax ),ml+mr+nums[m]两者之中大的那一个

代码 Runtime110 ms Beats 65.10% Memory 67.9 MB Beats 8.86%

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        return maxSubArray(nums, 0, nums.size() - 1);
    }
private:
    int maxSubArray(vector<int>& nums, int l, int r) {
        if (l > r) return INT_MIN;
        int m = l + (r - l) / 2, ml = 0, mr = 0;
        int lmax = maxSubArray(nums, l, m - 1);
        int rmax = maxSubArray(nums, m + 1, r);
        for (int i = m - 1, sum = 0; i >= l; i--) {
            sum += nums[i];
            ml = max(sum, ml);
        }
        for (int i = m + 1, sum = 0; i <= r; i++) {
            sum += nums[i];
            mr = max(sum, mr);
        }
        return max(max(lmax, rmax), ml + mr + nums[m]);
    }
};

54. Spiral Matrix

题意:Leetcode Top 100 Liked Questions(序号53~74),leetcode,算法,c++,数据结构,学习

我的思路

死做

代码 Runtime 0 ms Beats 100% Memory6.9 MB Beats 61.55%

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        int dy[]={1, 0,-1,0};
        int dx[]={0, 1, 0,-1};
        bool vis[19][19]={0};
        int m=matrix.size(),n=matrix[0].size();
        int nowx=0,nowy=0,mod=0;
        int nx=0,ny=0;
        vector<int> ans;
        for(int i=0;i<m*n;i++){//首先循环一开始的新来的一定是可以的
            nowx=nx,nowy=ny;
            vis[nowx][nowy]=1;
            ans.push_back(matrix[nowx][nowy]);
            if(i+1==m*n)break;
            nx=nowx+dx[mod];ny=nowy+dy[mod];
            while(nx<0||nx>=m||ny<0||ny>=n||vis[nx][ny]==1){
                mod=(mod+1)%4;nx=nowx+dx[mod];ny=nowy+dy[mod];
            }
        }
        return ans;
    }
};

55. Jump Game

题意:问能不能从索引0到索引n-1

我的思路

既然是问能不能到到终点,用贪心或者动态规划都可以,上次用了动态规划,这次就贪心吧

注意:记得 if(nums[0]==0&&n!=1)return 0;要特判

代码 Runtime 43 ms Beats 93.40% Memory48.3 MB Beats 74.51%

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int n=nums.size();
        if(nums[0]==0&&n!=1)return 0;
        for(int i=1;i<n-1;i++){
            nums[i]=max(nums[i]+i,nums[i-1]);
            if(nums[i]==i)return 0;
        }
        return 1;
    }
};

56. Merge Intervals

题意:返回重叠部分

Leetcode Top 100 Liked Questions(序号53~74),leetcode,算法,c++,数据结构,学习

我的思路

应该是要维护两端端点的,好像是-1 +1什么的?

做着做着发现这个interval还有start==end,这个-1和+1怎么做??

点的话就找一个bool数组特判吧

代码 Runtime19 ms Beats 99.65% Memory19.2 MB Beats 31.70%

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& in) {
        int vis[10004]={0};int n=in.size();int maxx=0;
        bool fl[10004]={0};//判点
        vector<vector<int>> ans;
        for(int i=0;i<n;i++){
            int st=in[i][0],en=in[i][1];
            maxx=max(maxx,en);
            if(st==en)fl[st]=1;
            else vis[st]++,vis[en]--;
        }
        int st=0,en=0,sum=0;
        int mod=1;//mod1是找正数,找到正数了切换mod-1找负数
        for(int i=0;i<=maxx;i++){
            sum=sum+vis[i];
            if(mod==1&&sum>0){st=i;mod=-mod;}
            else if(mod==-1&&sum==0){
                en=i;mod=-mod;
                ans.push_back({st,en});
            }
            else if(fl[i]&&mod==1){
                ans.push_back({i,i});
            }
        }
        return ans;
    }
};

标答 排序

标答的时间复杂度为O(n+logn)

首先将interval排序,应该是按照覆盖的起点排序,起点从小到大排序

遍历每个覆盖域,首先是第一个覆盖区域,初始化start和end;之后不断地找大的end,直到目前最大的end小于新来的start,这时把起点和重点放到答案列表中,更新起点和终点

代码 Runtime 23 ms Beats 98.10% Memory19 MB Beats 71.5%

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        vector<vector<int>> ans;
        int n=intervals.size();
        sort(intervals.begin(),intervals.end());
        int start=intervals[0][0];
        int end=intervals[0][1];
        for(int i=1;i<n;i++){
            if(end<intervals[i][0]){
                ans.push_back({start,end});
                start=intervals[i][0];
                end=intervals[i][1];
            }
            else{
                end=max(intervals[i][1],end);
            }
        }
        ans.push_back({start,end});
        return ans;
    }
};

62. Unique Paths

题意:机器人只能向下或者向右走,要从grid[0][0]走到grid[m-1][n-1]

我的思路

好像是组合数?按按计算器看看能不能推出来,没推出来

好像递归也是能够做出来的?不过走楼梯是一维的c[i+1]+c[i+2]得到的?

那么假设c是方案数,就先按照下面这个图建立一个二维数组做?

【看标答,这种方法居然是dp】

Leetcode Top 100 Liked Questions(序号53~74),leetcode,算法,c++,数据结构,学习

代码 Runtime 0 ms Beats 100% Memory6 MB Beats 87.9%

class Solution {
public:
    int uniquePaths(int m, int n) {
        int st[104][104]={0};st[m-1][n-1]=1;
        for(int i=m-1;i>=0;i--)
            for(int j=n-1;j>=0;j--)
                st[i][j]+=(st[i+1][j]+st[i][j+1]);
        return st[0][0];
    }
};

标答 组合数

在这个图上,一共要走m+n-2步,其中有m-1步是向下的,n-1步是向右的,这可以转换成m-1个向下n-1个向右的排序(图源知乎)

Leetcode Top 100 Liked Questions(序号53~74),leetcode,算法,c++,数据结构,学习

代码 Runtime 0 ms Beats 100.00% Memory 6 MB Beats 87.9%

class Solution {
public:
    int uniquePaths(int m, int n) {
        int N = n+m-2; // total steps = n-1 + m-1
        int r = min(n,m)-1; 
// will iterate on the minimum for efficiency = (total) C (min(right, down)
        double res = 1;// compute nCr
        for(int i=1; i<=r; ++i, N--)
            res = res*(N)/i;
        return (int)res;
    }
};

64. Minimum Path Sum

题意:二维地图,只能向下或者向右走,找到所有路径上的最小的值。

我的思路

这个肯定是dp吧;还是相同的道理,但是要注意边缘处理

dp[i][j]=num[i][j]+min(dp[i+1][j],dp[i][j+1])

Leetcode Top 100 Liked Questions(序号53~74),leetcode,算法,c++,数据结构,学习

代码 Runtime 6 ms Beats 88.72% Memory 9.7 MB Beats 89.19%

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int m=grid.size(),n=grid[0].size();
        for(int i=m-1;i>=0;i--){
            for(int j=n-1;j>=0;j--){
                if(i==m-1 && j==n-1)continue;
                if(i==m-1)grid[i][j]+=grid[i][j+1];
                else if(j==n-1)grid[i][j]+=grid[i+1][j];
                else grid[i][j]+=min(grid[i+1][j],grid[i][j+1]);
            }
        }
        return grid[0][0];
    }
};

70. Climbing Stairs

题意:爬楼梯,只能走1或2步,问到终点要走多少步

我的思路

n=1,c=1;n=2,c=2;n=3,c=3;c[i]=c[i-1]+c[i-2]

代码 Runtime 0 ms Beats 100% Memory 5.9 MB Beats 94.85%

class Solution {
public:
    int climbStairs(int n) {
        if(n<3) return n;
        int a=1,b=2,c=0;
        for(int i=3;i<=n;i++){
            c=a+b;a=b;b=c;
        }
        return c;
    }
};

72. Edit Distance

题意:三个操作:插入一个字母,删除一个字母,替换一个字母;问从字符串1变成字符串2最少需要多少步?

我的思路

(因为之前没保存,就只贴图片了) 

Leetcode Top 100 Liked Questions(序号53~74),leetcode,算法,c++,数据结构,学习

标答 动态规划

Leetcode Top 100 Liked Questions(序号53~74),leetcode,算法,c++,数据结构,学习

如果word1[0..i-1)+word2[j-1]=word2[0..j),要在i中插入word2[j-1],所以dp[i][j]=dp[i][j-1]+1

Q:为什么是dp[i][j]=dp[i][j-1]+1?

        因为word1[0..i-1)+word2[j-1]=word1[0..i)=word2[0..j),有word2[0..j)之前先有word2[0..j-1)所以知道了word1[0..i-1)如何转换成word2[0..j-1),因此word1[0..i)转换为word2[0..j)就是在word1[0..i-1)上增加了一步操作

 所以当word1[i - 1] != word2[j - 1]时,从三种操作中找出最小的那个

代码 Runtime 23 ms Beats 32.61% Memory7.3 MB Beats 81.80%(ON^2)

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m=word1.size(), n=word2.size();
        int dp[505][505]={0};
        for(int i=1;i<=m;i++)dp[i][0]=i;//注意初始化的范围
        for(int i=1;i<=n;i++)dp[0][i]=i;
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                if(word1[i-1]==word2[j-1])
                    dp[i][j]=dp[i-1][j-1];//注意这里的等于号
                else
                    dp[i][j]=min(min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1])+1;
            }
        }
        return dp[m][n];
    }
};

接下来把二维数组改成一维数组,从上面的代码可以看到,只需要dp[i - 1][j - 1],dp[i][j - 1] 和 dp[i - 1][j],所以可以用pre数组来代替dp[i-1]

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size();
        vector<int> pre(n + 1, 0), cur(n + 1, 0);
        for (int j = 1; j <= n; j++) {//因为是dp[i-1]的初始化,所以长度为word2的长度
            pre[j] = j;
        }
        for (int i = 1; i <= m; i++) {
            cur[0] = i;
            for (int j = 1; j <= n; j++) {
                if (word1[i - 1] == word2[j - 1]) {
                    cur[j] = pre[j - 1];
                } else {
                    cur[j] = min(pre[j - 1], min(cur[j - 1], pre[j])) + 1;
                }
            }
            fill(pre.begin(), pre.end(), 0);
            swap(pre, cur);
        }
        return pre[n];
    }
};

最后可以直接将pre数组省略成pre

!代码 Runtime 7 ms Beats 90.23% Memory 6.3 MB Beats 97.78%

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size(), pre;
        vector<int> cur(n + 1, 0);
        for (int j = 1; j <= n; j++) //初始化
            cur[j] = j;
        for (int i = 1; i <= m; i++) {
            pre = cur[0];
            cur[0] = i;
            for (int j = 1; j <= n; j++) {
                int temp = cur[j];
                if (word1[i-1] == word2[j-1])
                    cur[j] = pre;
                else 
                    cur[j] = min(pre, min(cur[j - 1], cur[j])) + 1;
                pre = temp;
            }
        }
        return cur[n];
    }
};

73. Set Matrix Zeroes

题意:set its entire row and column to 0Leetcode Top 100 Liked Questions(序号53~74),leetcode,算法,c++,数据结构,学习

我的思路

方案一 创建一个vis用来记录0,之后按照vis来修改,空间是O(mn)【这肯定做得出来】

方案二 设计一个创建一个长为n行的数组a,长为m的数组b;a记录下0在哪几行出现,b记录一下0在哪几列出现,之后修改,空间 Om+n 同时也符合"devise a constant space solution"

代码 Runtime 12 ms Beats 80.19% Memory13.3 MB Beats 74.42%

class Solution {
public:
    void setZeroes(vector<vector<int>>& ma) {
        int m=ma.size(),n=ma[0].size();
        bool a[204]={0};bool b[204]={0};
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(ma[i][j]==0){
                    a[i]=1,b[j]=1;
                }
            }
        }
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                if(a[i]||b[j]) ma[i][j]=0;
        return ;
    }
};

标答 O(1)空间复杂度

先把行全部处理了,之后再把列全部处理了

首先遍历行

代码 Runtime 3 ms Beats 99.86% Memory13.3 MB Beats 45.87%

void setZeroes(vector<vector<int> > &matrix) {
    int col0 = 1, rows = matrix.size(), cols = matrix[0].size();

    for (int i = 0; i < rows; i++) {
        if (matrix[i][0] == 0) col0 = 0;
        for (int j = 1; j < cols; j++)
            if (matrix[i][j] == 0)
                matrix[i][0] = matrix[0][j] = 0;
    }

    for (int i = rows - 1; i >= 0; i--) {
        for (int j = cols - 1; j >= 1; j--)
            if (matrix[i][0] == 0 || matrix[0][j] == 0)
                matrix[i][j] = 0;
        if (col0 == 0) matrix[i][0] = 0;
    }
}

74. Search a 2D Matrix

题意:矩阵中是否存在target

我的思路

两次查找

代码 Runtime3 ms Beats 75.49% Memory 9.6 MB Beats 8.44%

class Solution {
public:
    int bis(int l,int r,vector<vector<int>>& mat, int target){
        while(l<=r){
            int mid=(l+r)/2;
            if(mat[mid][0]<target) l=mid+1;
            else if(mat[mid][0]==target) return mid;
            else r=mid-1;
        }
        return l-1;
    }

    bool bishe(int q, int l,int r,vector<vector<int>>& mat, int target){
        while(l<=r){
            int mid=(l+r)/2;
            if(mat[q][mid]<target) l=mid+1;
            else if(mat[q][mid]==target) return 1;
            else r=mid-1;
        }
        return 0;
    }

    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int n=matrix.size();int i=0;
        if(target<matrix[0][0])return 0;
        int q=bis(0,n-1,matrix,target);
        int m=matrix[0].size();
        return bishe(q,0,m-1,matrix,target);
    }
};

标答

ummm就这样吧,标答是先On,之后Ologn的文章来源地址https://www.toymoban.com/news/detail-654557.html

代码 Runtime 3 ms Beats 75.49% Memory 9.4 MB Beats 67.2%

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int lent = matrix.size();
        int widt= matrix[0].size();
        int tart=0;
        for(int i=0; i<lent; i++){
            if (matrix[i][widt-1] >= target){
                tart = i; break;
            }
        } 
        int low = 0;
        int high = widt-1;
        int mid;
        while(low<=high){
            mid = (low+((high-low)/2)); 
            if(matrix[tart][mid] == target)
                return true;
            else if (matrix[tart][mid] < target)
                low = mid+1;
            else
                high = mid-1;
        }
        return false;
    }
};

到了这里,关于Leetcode Top 100 Liked Questions(序号53~74)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Leetcode】top 100 图论

    基础知识补充 1.图分为有向图和无向图,有权图和无权图; 2.图的表示方法:邻接矩阵适合表示稠密图,邻接表适合表示稀疏图;    邻接矩阵:    邻接表: 基础操作补充 1.邻接矩阵: 2.邻接表: 3.图的遍历:  题目 200 岛屿数量 给你一个由  \\\'1\\\' (陆地)和  \\\'0\\\' (水)组

    2024年04月10日
    浏览(33)
  • 【Leetcode】top 100 多维动态规划

    62 不同路径 一个机器人位于一个  m x n   网格的左上角,机器人每次只能向下或者向右移动一步,机器人试图达到网格的右下角,问总共有多少条不同的路径? 分析:dp[i][j] 代表走到 (i, j) 的路径总和数 递推规律:dp[i][j] = dp[i-1][j] + dp[i][j-1] 初始条件:dp[0][:] = 1 dp[:][0] = 1

    2024年03月26日
    浏览(36)
  • LeetCode - #85 最大矩形(Top 100)

    本题为 LeetCode 前 100 高频题 本题由于没有合适答案为以往遗留问题,最近有时间将以往遗留问题一一完善。 我们社区陆续会将顾毅( Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。 )的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我

    2024年02月10日
    浏览(29)
  • 算法leetcode|74. 搜索二维矩阵(rust重拳出击)

    给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非递减顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。 m == matrix.length n == matrix[i].length 1 = m, n = 100 -10 4 = matrix[i][j],

    2024年02月11日
    浏览(24)
  • 算法leetcode|53. 最大子数组和(rust重拳出击)

    给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 1 = nums.length = 10 5 -10 4 = nums[i] = 10 4 面对这道算法题目,二当家的再次陷入了沉思。 刚开始以为要暴力破解,双循环什么的,但

    2024年02月08日
    浏览(34)
  • 算法训练day31贪心算法理论基础Leetcode455分发饼干376摆动序列53最大子序和

    文章链接 代码随想录 (programmercarl.com) 说实话贪心算法并没有固定的套路 。 最好用的策略就是举反例,如果想不到反例,那么就试一试贪心吧 。 面试中基本不会让面试者现场证明贪心的合理性,代码写出来跑过测试用例即可,或者自己能自圆其说理由就行了 。 刷题或者面

    2024年02月20日
    浏览(35)
  • Leetcode171. Excel 表列序号

    给你一个字符串  columnTitle  ,表示 Excel 表格中的列名称。返回  该列名称对应的列序号  。 例如: 题解:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 代码如下: 与本题互逆的题目,在之前的「每日一题」就出现过了,你可以一同复习一下 ~

    2024年02月07日
    浏览(23)
  • 【LeetCode 热题 100】矩阵 专题(大多原地算法,需要一定思维)

    解题思路 在 代码注释中!

    2024年02月15日
    浏览(31)
  • LeetCode每日一题——1331.数组序号转换

    题目传送门 给你一个整数数组 arr ,请你将数组中的每个元素替换为它们排序后的序号。 序号代表了一个元素有多大。序号编号的规则如下: 序号从 1 开始编号。 一个元素越大,那么序号越大。如果两个元素相等,那么它们的序号相同。 每个数字的序号都应该尽可能地小。

    2024年02月14日
    浏览(25)
  • leetcode-Excel 表列序号

    171. Excel 表列序号 本题与168. Excel表列名称 是互为逆向的 题解: 其实这就是一个26进制数的转换,我们以AB为例,A目前是最高位,那他的值是26*1,因为A对应的是1,B是2,所以值为28

    2024年01月25日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包