首页 > 编程语言 >[算法]区间归并

[算法]区间归并

时间:2022-08-26 02:44:07浏览次数:90  
标签:归并 int interval 交集 算法 intervals result 区间

问题分析

有的时候,会遇到给定一系列的区间,求交集or并集,或者合并的题.

这些题的解题方式比较通用个,做一个总结.

会用到集合和归并排序的相关知识.

两个区间的关系有六种,如果我们首先对区间按照区间左边界进行排序,那么就会编程3中关系:

A 包含  B ==> A[0] <= B[0] && A[1] >= B[1]

A 交集于  B  ==> A[0] <= B[0] || A[1]  >= B[1]

A 无交集 B ==>  A[1] < B[0]

 

解题套路

算法的题解法是:

首先对 区间集合进行排序.

将这些集合分为已归并 + 未归并

从已归并中取出最后一个  + 未归并的第一个进行计算:

根据以上的三种关系来处理已归并集合的最后一个区间:

A 包含  B ==> A[0] <= B[0] && A[1] >= B[1]   ==>  未归并 自动归并到已归并集合,不用处理

A 交集于  B  ==> A[0] <= B[0] || A[1]  >= B[1]  ==>  修改 已归并最后一个区间的右区间  为B[1]

A 无交集 B ==>  A[1] < B[0]   ==>   将B 区间添加到已归并区间中

 

示例

56. 合并区间

 

 

题解

 

class Solution {
    public int[][] merge(int[][] intervals) {

        /**
         * 首先做一个排序.按照做区间进行排序.将关系变为三种. 然后进行处理.
         * 区间的关系有三种:
         * 第一种是完全没有交集的.
         * 第二种是有交集,不是子集
         * 第三种是:有交集,是子集.
         */

        Arrays.sort(intervals, new Comparator<int[]>() {
            @Override
            public int compare(int[] here, int[] there) {
                if (here[0] != there[0]) {
                    return here[0] - there[0];
                } else {
                    return here[1] - there[1];
                }
            }
        });
        //左侧是最小的.
        List<int[]> result = new ArrayList<int[]>();
        result.add(intervals[0]);
        for (int i = 1; i < intervals.length; i++) {
            int[] interval = intervals[i];
            int[] top = result.get(result.size() - 1);
            if (interval[0] <= top[1]) {
                //有交集
                if (interval[1] >= top[1]) {
                    top[1] = interval[1];
                }
                //子集忽略
            } else {
                //无交集,之间的结束
                result.add(interval);
            }
        }
  

        return result.toArray(new int[result.size()][]);
    }

}

 

986. 区间列表的交集

 

 

题解:

class Solution {
   public int[][] intervalIntersection(int[][] firstList, int[][] secondList) {

        /**
         * 求出交集的实现方式.首先将所有的元素进行排序,然后不断的求并集,然后依次用后面的和前面的取交集
         */

        /**
         * 这个题中,内部不相交,所以只需要和另外一个数组中的区间取交集就好了.如果一旦取过以后,就没有交集了.类似于归并排序.
         */
        int firstRank = 0, secondRank = 0;
        List<int[]> result = new ArrayList<>();
        while (firstRank < firstList.length && secondRank < secondList.length) {
            int low = Math.max(firstList[firstRank][0], secondList[secondRank][0]);
            int high = Math.min(firstList[firstRank][1], secondList[secondRank][1]);

            if (low <= high) {
                result.add(new int[]{low, high});
            }

            if (firstList[firstRank][1] == high) {
                firstRank++;
            }
            if (secondList[secondRank][1] == high) {
                secondRank++;
            }
        }
        return result.toArray(new int[0][2]);
    }
}

 

57. 插入区间

 

 题解:

class Solution {
   public int[][] insert(int[][] intervals, int[] newInterval) {

        List<int[]> result = new ArrayList<>();
        boolean newAccepted = false;
        int left = 0;
    //这里套用了 归并排序模板 while (left < intervals.length || !newAccepted) { int[] interval = null; if (newAccepted) { interval = intervals[left++]; } else if (left >= intervals.length) { interval = newInterval; newAccepted = true; } else if (intervals[left][0] < newInterval[0] || (intervals[left][0] == newInterval[0] && intervals[left][1] < newInterval[1])) { interval = intervals[left++]; } else { interval = newInterval; newAccepted = true; } if (result.size() == 0) { result.add(new int[]{interval[0], interval[1]}); } else { int[] top = result.get(result.size() - 1); if (interval[0] <= top[1]) { //有交集 if (interval[1] > top[1]) { //交集集 top[1] = interval[1]; } //子集不用管 } else { //没有交集 result.add(new int[]{interval[0], interval[1]}); } } } return result.toArray(new int[0][]); } }

  

 

标签:归并,int,interval,交集,算法,intervals,result,区间
From: https://www.cnblogs.com/xxuuzz/p/16626323.html

相关文章

  • 2022“杭电杯”中国大学生算法设计超级联赛(10) 题解
    C.WavyTree发现修改次数和相邻两数的相对大小有关,所以可先求出差分数组。分两种情况考虑:①奇数位置为波峰②偶数位置为波峰。以情况①为例,若奇数位置差分后值小......
  • 数据结构与算法分析--C语言描述 pdf
    高清扫描版下载链接:https://pan.baidu.com/s/1BGsOOAOqXE9j509OFtkjXA点击这里获取提取码书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能......
  • 数据结构与算法分析 Java版 pdf
    高清扫描版下载链接:https://pan.baidu.com/s/1vDsOy1E0kHizahB6hIg2tA点击这里获取提取码本书以Java语言为基础,讨论了数据结构的线性结构和非线性结构及其实现,全书以Java......
  • 算法学习--广度优先搜索和深度优先搜索
    广度优先搜索BFS一、相关概念1.图的遍历:从图中某一顶点出发,按照某种搜索方法沿着图中的边对图中的所有节点访问一次且仅访问一次二、算法流程首先访问起始顶点v;......
  • 区间问题----多次区间修改,少次单点询问的差分
    《定义》对于原数列:a1a2a3.....aiaj........an-1an这个数列的差分为ca[j]=aj-ai这个数列的前缀和为he[j]=aj+ai+..+a2+a1 我们可以惊奇的发现差分的前缀和==原......
  • vue 3.0 国密sm2算法加密解密文件流
     针对文件流加密需要考虑性能问题,所以选择部分文件字节加密,破坏文件内容,达到用户不能随意下载打开文件 ts文件:import{sm2}from'sm-crypto';import{Buffer}......
  • 洛谷P1001 A+B problem最全算法
    为防止大家说我误导新人,先放一个最不正常的代码。#include<iostream>usingnamespacestd;intmain(){inta,b;cin>>a>>b;cout<<a+b;ret......
  • tarjan算法求强连通分量
    \(tarjan\)算法求强连通分量\(tarjan\)算法简介我在这篇博客中讲过\(tarjan\)算法的简介和求割点与桥,就不再讲述。强连通分量强连通图是指一个有向图内任意两点都能互......
  • YBTOJ 贪心算法合集
    奶牛晒衣服开个堆,记录个时间,每次抠出来堆顶减去b再扔回去就做完了。read(n,a,b);rep(i,1,n)read(h[i]);priority_queue<int>q;rep(i,1,n)q.push(h[i]);in......
  • YBTOJ 递推算法合集
    错排问题令\(dp[i]\)表示一个\(i\)的排列的方案数。考虑当前插入一个数\(i\),那么考虑一个位置\(pos\),显然\(pos\)有\(i-1\)种选择假设\(i\)放在了\(......