刷题日记 day 5

本文探讨了贪心算法在解决LeetCode中的两道题目——最大子序和与跳跃游戏上的应用,强调贪心算法的重要性。通过实例解析,展示了如何从局部最优解逐步构建全局最优解,指出贪心算法虽无固定模板,但理解其思想对于问题解决至关重要。作者通过对比暴力解法,突显贪心算法在效率上的优势,并分享了踩坑与积累经验对于掌握算法的关键作用。
摘要由CSDN通过智能技术生成

初探贪心算法

​ 终于结束了回溯,老实说回溯是真的有点难,虽然有模板,但是很多问题的解决方式不尽相同。刷了也有20道题差不多,但是真正有印象的就几题。不过现在学到贪心了,我有点难受。它没有模板,就一个局部最优的算法思想。但是解决问题想到了这个思想,真的非常简单。想不到就呵呵了。

两个题目

下面是我今天被贪心折磨的日常:

LeetCode第53题 最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [0]
输出:0

示例 4:

输入:nums = [-1]
输出:-1

示例 5:

输入:nums = [-100000]
输出:-100000

提示:

1 <= nums.length <= 3 * 104
-105 <= nums[i] <= 105

暴力解法

class Solution {
    public int maxSubArray(int[] nums) {
        int maxValue=Integer.MIN_VALUE;
        
        for(int i=0;i<nums.length;i++){
            int count=0;
            for(int j=i;j<nums.length;j++){
                count+=nums[j];
                maxValue=count>maxValue?count:maxValue;
            }
        }
        return maxValue;
    }
}

时间复杂度是:O(n^2)

但是如果用贪心算法来写:

class Solution {
    public int maxSubArray(int[] nums) {
         int maxValue=Integer.MIN_VALUE;
        int count=0;
        for(int i=0;i<nums.length;i++){
            count+=nums[i];
            if(count>maxValue)
                maxValue=count;
            if(count<0)
                count=0;
        }
        return maxValue;
    }
}

这个算法的时间复杂度很明显是O(n),初看还不是很明白,其实就是用了一个小技巧:我们都知道如果count后面加的是一个负数,就一定会让和变小,所以我们一旦碰到让count小于0的数据,就直接将count初始化为0,在从头开始记录count。这样看起来就使每一步都使得count是最大的,因为让count变成负数的元素我不会加入。这就是贪心的体现,但是这个很难想到呀!所以说贪心没有模板、只有一次次的踩坑积累经验,才可能想到有时候可以使用贪心。

LeetCode第55题 跳跃游戏

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。

示例 1:

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例 2:

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

1 <= nums.length <= 3 * 104
0 <= nums[i] <= 105

这个题目就有点符合现实了,有点像跳台阶,其实可以从后往前跳,判断前一个节点是否能到达最后一个节点,如果可以就更新当前节点为最后一个节点。这是一种思路。但是贪心法更赖皮:

class Solution {
    public boolean canJump(int[] nums) {
        int cover=0;
        if(nums.length==1)
            return true;
        for(int i=0;i<=cover;i++){
            cover=Math.max(i+nums[i],cover);
            if(cover>=nums.length-1)
                return true;
        }
        return false;
    }
}

看完也是不明所以,看了题解后感慨十分赖皮!其实就是看一个覆盖范围。你当前能走的步数的最大值是否覆盖到了最后一个元素,如果是肯定能走到。每次更新最大覆盖范围,这也是贪心法。

分析与小结

做贪心的题目就感觉手上有本秘籍,很厉害。但是就是不会用,但是当你以为它就是废物时,丢掉了,别人捡起来,看了秘籍后成了你梦想成为的人。唉。任重而道远!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值