贪心算法及相关leetcode习题详解 java代码实现

前言

这篇博客,南国根据自己之前一段时间的学习和刷题,对贪心算法这一知识点做个小的归纳。这篇博客的内容首先是基础知识点,随后是具体的实战习题。话不多说,干货速来~

基础知识点

在计算机专业常见的极大算法里面,贪心算法算是比较好理解的了。一句话用来概括就是,贪心算法:在对问题求解时,总是做出当前看来最好的选择
在这里插入图片描述
这个问题的本质借助的就是贪心算法。考虑当前的决定就是最好的情况。

贪心有许多非常经典的应用,例如说霍夫曼编码,最小生成树算法,Dijkstra单源最短路径等。

其实对于贪心算法,总结的概括性话并不多。它并不像动态规划那样有我们常说的“一个模型三个特征”,也不像回溯算法那样需要递归。关于这两个 在后续博客中,南国有时间会在继续更新。当然不是所有用贪心算法解决的问题他都是给出了最优解。

接下来,我们就通过一些实战的题目来进行算法具体讲解。

实战习题

1.分配饼干

leetcode 455 Assign Cookies
这是非常经典的一道贪心算法的题,难度不大。

解题思路:给一个孩子的饼干应当尽量小又能满足该孩子,这样大饼干就能拿来给满足度比较大的孩子。因为最小的孩子最容易得到满足,所以先满足最小的孩子。

证明:假设在某次选择中,贪心策略选择给当前满足度最小的孩子分配第 m 个饼干,第 m 个饼干为可以满足该孩子的最小饼干。假设存在一种最优策略,给该孩子分配第 n 个饼干,并且 m < n。我们可以发现,经过这一轮分配,贪心策略分配后剩下的饼干一定有一个比最优策略来得大。因此在后续的分配中,贪心策略一定能满足更多的孩子。也就是说在这个问题中不存在比贪心策略更优的策略,即贪心策略就是最优策略。

所以我们首先对两个数组进行升序排序好,然后尝试着把最小的饼干分配给需求最小的小孩,这样逐次对应,求出最多可以满足多少个小孩。

Java实现代码:

package GreedyAlgorithm;

import java.util.Arrays;

/**
 * leetcode 455 Assign Cookies
 * @author xjh 2019.02.27
 * 贪心算法的典型案例 经常看 经常做!!
 */
public class t455_AssignCookies {
    public int findContentChildren(int[] g, int[] s) {
        //1.首先对两个数组及逆行排序
        Arrays.sort(g);Arrays.sort(s);
        int gi=0,si=0;
        while (gi<g.length&&si<s.length){
            if (g[gi]<=s[si]) gi++; //比较遍历到的最小值
            si++;
        }
        return gi;
    }
}

2.不重叠区间个数

leetcode 435 Non-overlapping Intervals
题目的要求是给定一组区间,找出需要删除的最小区间个数,以使其余的区间不重叠。
解题思路:
想要找到删除空间的最小个数count,对应的就是找到最多能组成不重叠的个数m 这m个区间去填满从最小下标到最大下标的值。count=n-m

在每次选择时,区间的结尾很重要,结尾越小,留给后面的空间越大,则m也会越大,count就越小。

Java实现代码:

package GreedyAlgorithm;

import java.util.Arrays;
import java.util.Comparator;

/**
 * leetcode 435 Non-overlappingIntervals
 * 贪心算法的典型案例:计算让一组区间不重叠所需要移除的区间个数。[经常练习 回顾]
 * 首先需要计算出最多的可不重叠的区间个数m 然后总个数n减去m
 * 计算m 采用贪心算法:我们每次选择的时候,左端点跟前面的已经覆盖的区间不重合的,
    * 右端点又尽量小的,这样可以让剩下的未覆盖区间尽可能的大,就可以放置更多的区间。
 * @author xjh 2019.02.27
 */
public class t435_NonoverlappingIntervals {
     public class Interval {
      int start;
      int end;
      Interval() { start = 0; end = 0; }
      Interval(int s, int e) { start = s; end = e; }
  }
    public int eraseOverlapIntervals(Interval[] intervals) {
         if (intervals.length==0||intervals.length==1) return 0;
         //1.贪心的第一步 首先需要对区间end进行排序 这里是升序
        Arrays.sort(intervals, new Comparator<Interval>() {
            @Override
            public int compare(Interval o1, Interval o2) {
                return o1.end-o2.end;
            }
        });
        //上面这个排序语句 可以用lambda表达式简写为:
        //Arrays.sort(intervals,Compar
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值