LeetCode Hot100第2期 ! ! !

LeetCode Hot100刷题指南(第二期)

大家好 我是寸铁👊

临近秋招,让我们一起刷题吧👏

每期5道题 持续更新中🏃

欢迎点赞 + 关注 💖

往期回顾

操作系统期末题库 第五期

蓝桥杯 Java 省赛 B 组(初赛)填空题

LeetCode Hot100 刷题(第一期)

idea创建SpringBoot项目报错解决方案

数据库SQL语句(期末冲刺)

第5期

53. 最大子数组和

分析

要找出一个最大和的连续子数组
不妨枚举以每个数结尾的最大连续子数组

思想

动态规划:
有两种选择:
一种是单独一个数
一种是和前面的数字合并成一个数组
我们可以对这两种情况取一个最大值
再更新当前的最大和

时间复杂度

枚举n个数字,一重for循环。
时间复杂度为O(n)

Accode

class Solution {
    public int maxSubArray(int[] nums) {
        int pre = 0 , ans = nums[0];
        for(int x : nums){
            pre = Math.max(pre + x , x);
            ans =  Math.max(pre , ans);
        }
        return ans;
    }
}

56. 合并区间

分析

先对数组区间进行排序,先对左端点排序,再对右端点排序。
合并分为3种情况:
1.上一个区间的左端点和下一个区间的左端点相等
则区间的左端点更新为上一区间的左端点。
区间的右端点更新为下一区间的右端点。
2.下一个区间的左端点在上一个区间的左端点和下一个区间的右端点之间
则更新区间的左端点为上一个区间的左端点。
右端点更新为下一个区间的右端点
3.没有重合,则不用合并。

可以发现,除了第3种情况,剩下两种情况的处理结果一致
我们可以单独为第3种情况进行特判
再对1、2情况进行合并即可
1、2两种情况的左端点其实不用更新,只需要更新右端点即可
更新方式为取当前两个区间的右端点的最大值

时间复杂度

一重for循环即可实现
总计:O(n)

ACcode

class Solution {
    public int[][] merge(int[][] a) {
        List<int []> res = new ArrayList<>();
        Arrays.sort(a , (x , y)-> x[0] - y[0]);
        int l = a[0][0] , r = a[0][1]; 
        for(int i = 1; i < a.length; i++){
         //没有重合的端点
            if(a[i][0] > r){
                res.add(new int []{l , r});
                l = a[i][0];
                r = a[i][1];
            }
        //有重合的端点,更新右端点即可。
            else{
                r = Math.max(r , a[i][1]);
            }
            }
            res.add(new int []{l , r});
            return res.toArray(new int[0][]);
        }


    }

189. 轮转数组

解题思路

翻转数组,对数组中的每个数字向右移动 k 步后翻转。
数组长度为 n ,对于数组的数组下标 i
移动k步进行数组元素翻转, 即 i + k
(i+k) % n获得在数组中翻转的相对位置
如果说某个位置i 出现(i + k ) % n == 0
则说明i后面的数字翻转时,翻转的位置从下标0开始。

注意

arr[]数组为空数组
移动后的位置对应的元素为nums[i]
需要再把nums[i]的值复制到移动后的位置上的arr[]

代码

class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        int []arr = new int[n];
        for(int i = 0; i < n; i++){
            arr[(i + k) % n] = nums[i];
        }
        System.arraycopy(arr, 0, nums , 0 , n);
        
    }
}

238. 除自身以外数组的乘积

解题思路

假设当前下标为i
除自身外的乘积可以分为两部分乘积相乘
一部分是左半部分即i - 1 即L[i]
一部分是右半部分即i + 1 即R[i]
再将这两半部分乘积即可:L[i] * R[i]

注意

L[i]:第i个数的左边的乘积
R[i]: 第i个数的右边的乘积
初始化:
L[0] = 1
R[n-1]=1
用于后面数字的累乘
由于L[0] = 1
所以L[]循环的终止条件
i = 1; i < n

由于R[n-1] = 1
所以R[]循环的终止条件
i = n-2; i >= 0

Accode
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int L[] = new int [n];
        int R[] = new int [n];
        int ans[] = new int [n];
        L[0] = 1;
        for(int i = 1; i < n ; i++){
            L[i] = L[i - 1] * nums[i - 1];
        }
        R[n - 1] = 1;
        for(int i = n - 2; i >= 0; i--){
            R[i] = R[i + 1] * nums[i + 1];
        }
        for(int i = 0; i < n; i++){
            ans[i] = L[i] * R[i];
        }
        return ans;
    }
}

73. 矩阵置零

解题思路

先看数据范围:1 <= m, n <= 200
两重for循环枚举最多为O(m*n) = O(40000)可以过
我们只需要在矩阵中遇到数字为0的位置
记录当前数字所在的行数和列数
再去更新该行的每一个列数字均为0
更新该列的每一行数字均为0

时间复杂度

两重for循环枚举最多为 O(mn)

Accode

class Solution {
    public void setZeroes(int[][]a) {
        int n = a.length;
        int m = a[0].length;
        boolean [] row = new boolean[n];//行
        boolean [] col = new boolean[m];//列
        for(int i=0; i < n; i++){
            for(int j = 0; j < m; j++){
               if(a[i][j] == 0){
                  row[i] = col[j] = true;//记录 i行 j列 
               }
               
            }
        }
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(row [i] || col[j]){
                    a[i][j] = 0;
                }
            }
        }
    }
}

☀️☀️☀️☀️☀️☀️
后续有补充,持续更新中🌋
喜欢的伙伴点点赞,关个注💗

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寸 铁

感谢您的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值