java 贪心算法(无重复区间)


java 贪心算法(无重复区间)

 

 

*************************

贪心算法

 

算法描述:原问题可拆解为多阶段进行,每个阶段都做出当前阶段的最优选择(当前阶段最优不一定是全局最优)

适用场景:如果当前阶段做出的选择是否为全局最优后续阶段的选择无关(无后效性),则可使用贪心算法

 

不适用示例:三角形最短路径和

                      

贪心算法解:2 ==> 3 ==> 5 ==> 1,为全局最优解

 

                      

贪心算法解:2 ==> 3 ==> 60 ==> 1,不是全局最优解

全局最优解:2 ==> 4 ==> 7 ==> 3

 

三角形最短路径当前阶段的解是否为全局最优解与后续阶段的选取有关(即存在后效性),不可用贪心算法

 

 

*************************

示例:无重复区间

 

问题描述

给定一个区间集合,找到需要一处的区间的最小数量,使得剩余的空间不重叠

注意:可以假定区间的终点总是大于区间的起点;
区间[1,2]、[2,3]有接触,但是不重叠


示例 1:[1,2], [2,3], [3,4], [1,3]
输出:1, 移除[1,3]后,剩余区间不重叠

示例 2:[1,2], [1,2], [1,2]
输出:2,移除2个[1,2]后,剩余区间不重叠

示例 3:[1,2], [2,3]
输出:0, 原始区间不重叠

 

贪心算法:将区间按end排序,再按start排序

从第一个区间开始,遍历后面的区间,如果第一个区间与后面的区间重叠,移除后面的区间;

从第二个区间开始,遍历后面的区间,如果第二个区间与后面的区间重叠,移除后面的区间

重复执行上述过程,直至比较所有区间

 

class Interval implements Comparable<Interval> {

    private Integer start;
    private Integer end;

    public Integer getStart() {
        return start;
    }

    public void setStart(Integer start) {
        this.start = start;
    }

    public Integer getEnd() {
        return end;
    }

    public void setEnd(Integer end) {
        this.end = end;
    }

    @Override
    public int compareTo(Interval o) {
        if (this.getEnd()<o.getEnd()){
            return -1;
        }

        if (this.getEnd()>o.getEnd()){
            return 1;
        }

        return this.getStart().compareTo(o.getStart());
    }

    @Override
    public String toString() {
        return "["+this.getStart()+","+this.getEnd()+"] ";
    }
}

public class MyTest {

    public static List<Interval> generate(int num){
        Random random=new Random();

        List<Interval> list=new ArrayList<>();
        for (int i=0;i<num;i++){
            Interval interval=new Interval();

            int start=random.nextInt(100);
            int end=start+random.nextInt(20)+1;
            interval.setStart(start);
            interval.setEnd(end);

            list.add(interval);
        }

        return list;
    }

    public static void main(String[] args){
        List<Interval> list=generate(10);
        System.out.println("初始区间为:");
        list.forEach(System.out::print);

        Collections.sort(list);
        System.out.println("\n\n区间排序后:");
        list.forEach(System.out::print);

        int count=0;
        for (int i=0;i<list.size()-1;i++){
            for (int j=i+1;j<list.size();){
                if (list.get(i).getEnd()>list.get(j).getStart()){
                    list.remove(j);
                    count++;
                }else {
                    j++;
                }
            }
        }

        System.out.println("\n\n移除的区间数为:"+count);
        System.out.println("移除后区间为:");
        list.forEach(System.out::print);
    }
}

 

控制台输出

初始区间为:
[77,80] [86,88] [68,79] [93,113] [44,62] [28,31] [57,65] [32,49] [89,100] [66,67] 

区间排序后:
[28,31] [32,49] [44,62] [57,65] [66,67] [68,79] [77,80] [86,88] [89,100] [93,113] 

移除的区间数为:3
移除后区间为:
[28,31] [32,49] [57,65] [66,67] [68,79] [86,88] [89,100] 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值