【LeetCode热题100】打卡19天:最大数组和&跳跃游戏

【LeetCode热题100】打卡第19天:最大数组和&跳跃游戏

⛅前言

大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。

博客主页💖:知识汲取者的博客

LeetCode热题100专栏🚀:LeetCode热题100

Gitee地址📁:知识汲取者 (aghp) - Gitee.com

Github地址📁:Chinafrfq · GitHub

题目来源📢:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激

最大数组和

🔒题目

原题链接:53. 最大子数组和

在这里插入图片描述

🔑题解

  • 解法一:暴力(内存超限,210个数据通过200个)

    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    import java.util.stream.Collectors;
    
    /**
     * @author ghp
     * @title 最大数组和
     */
    class Solution {
        public int maxSubArray(int[] nums) {
            List<Integer> list = Arrays.stream(nums).boxed().collect(Collectors.toList());
            for (int i = 0; i < nums.length; i++) {
                int sum = nums[i];
                for (int j = i + 1; j < nums.length; j++) {
                    sum += nums[j];
                    list.add(sum);
                }
            }
            return Collections.max(list);
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( 2 n ) O(2^n) O(2n)

    其中 n n n 为数组中元素的个数

    不出所料,对于元素个数较少的情况,是可以通过的,但是遇到长度较大的时候会出现内存超限!

    在这里插入图片描述

    备注:Java规定一个方法编译后的字节码大小不能超过 65535 字节,这个长度在一般情况下都是够用的,但碰到极端情况就不行了

    /**
     * @author ghp
     * @title 最大数组和
     */
    class Solution {
        public int maxSubArray(int[] nums) {
            int max = Integer.MIN_VALUE;
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] > max){
                    max = nums[i];
                }
            }
            for (int i = 0; i < nums.length; i++) {
                int sum = nums[i];
                for (int j = i + 1; j < nums.length; j++) {
                    sum += nums[j];
                    if (sum>max){
                        max = sum;
                    }
                }
            }
            return max;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为数组中元素的个数

    这样写内存不超限了,但是时间超限!

  • 解法二:动态规划

    主要思路:因为我们是要求数组连续元素之和的最大值,所以每次我们在遍历数组时,有两种选择的可能性,要么是选择当前元素,要么是选择之前求的和加上当前元素。这样我们就可以得到一个递推式: M a t h . m a x ( s u m + n u m s [ i ] , n u m s [ i ] ) Math.max(sum+nums[i], nums[i]) Math.max(sum+nums[i],nums[i]),这里需要注意,我们要需要有一个变量来记录这个过程中出现的最大值,所以还应当有: M a t h . m a x ( m a x , s u m ) Math.max(max, sum) Math.max(max,sum)

    /**
     * @author ghp
     * @title 最大数组和
     */
    class Solution {
        public int maxSubArray(int[] nums) {
            int max = Integer.MIN_VALUE;
            int sum = 0;
            for (int i = 0; i < nums.length; i++) {
                sum = Math.max(sum+nums[i], nums[i]);
                max = Math.max(max, sum);
            }
            return sum;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为数组中元素的个数

  • 解法三

跳跃游戏

🔒题目

原题链接:55.跳跃游戏

在这里插入图片描述

🔑题解

  • 解法一:BFS(时间超限)

    主要不断进行搜索遍历,然后因为这相当于是一个带权的树,只要树的权值之和等于数组长度-1,就说明数组的最后一个元素可达。否则就不可达。

在这里插入图片描述

/**
 * @author ghp
 * @title 跳跃游戏
 */
class Solution {

    static boolean f = false;

    public boolean canJump(int[] nums) {
        int path = 0;
        bfs(nums, path);
        return f;
    }

    private void bfs(int[] nums, int path) {
        if (path >= nums.length - 1) {
            // 当前可达距离>=数组最大长度,说明可到达最后一个元素,结束递归
            f = true;
            return;
        }
        for (int i = 1; i <= nums[path]; i++) {
            // 遍历下一层
            bfs(nums, path + i);
        }
    }
}

复杂度分析:

  • 时间复杂度: O ( n ! ) O(n!) O(n!)
  • 空间复杂度: O ( 1 ) O(1) O(1)

其中 n n n 为数组中元素的个数

  • 解法二:贪心

    通过不断迭代,计算出当前可达的最大长度,只要最大长度超过数组的长度,就可以达到数组中的最后一个元素

    /**
     * @author ghp
     * @title 跳跃游戏
     */
    class Solution {
        public boolean canJump(int[] nums) {
            int max = Integer.MIN_VALUE;
            for (int i = 0; i < nums.length; i++) {
                if (i <= max){
                    // 当前距离是能够到达的
                    // 更新最大距离
                    max = Math.max(max, i + nums[i]);
                    if (max >= nums.length-1){
                        // 最大距离已经超过了数组的长度,所以可以到达最后一个元素
                        return true;
                    }
                }
            }
            return false;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为数组中元素的个数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

知识汲取者

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值