leetcode刷题笔记五十六和五十七 合并区间与插入区间

leetcode刷题笔记五十六和五十七 合并区间与插入区间


源地址:56. 合并区间

问题描述:

给出一个区间的集合,请合并所有重叠的区间。

示例 1:

输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:

输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

代码补充:

/**
如何判断区间可重叠?我们通过判断两个区间的尾端点与首端点的大小,当出现尾端点大于首端点情况,认为存在重叠情况
为防止出现[3,4][0,1]的情况,需要首先针对intervals的首端点进行排序
使用resi标记当前合并的位置
在整个遍历过程中,如果出现重叠区间,对刚刚合并的区间首尾端点进行更新
否则将区间放入res,更新resi位置

其中需要主要使用的intervals 首端点排序的方法

def sortInPlaceBy[B](f: (Char) => B)(implicit ord: Ordering[B]): StringBuilder.this.type

Sorts this mutable sequence in place according to the Ordering which results from transforming an implicitly given Ordering with a transformation function.
*/
object Solution {
    def merge(intervals: Array[Array[Int]]): Array[Array[Int]] = {
        val length = intervals.length
        if(length == 0 || length == 1) return intervals
		//数组首端点排序
        intervals.sortInPlaceBy{ a => a(0) }
        
        val res = Array.ofDim[Int](length,2)
        //将第一个节点放入,设置resi
        res(0)(0) = intervals(0)(0)
        res(0)(1) = intervals(0)(1)
        var resi = 0

        for( i <- 1 to length-1 ){
            if(res(resi)(1) >= intervals(i)(0) && res(resi)(0) <= intervals(i)(1)){
               res(resi)(1) = math.max(res(resi)(1), intervals(i)(1))
               res(resi)(0) = math.min(res(resi)(0), intervals(i)(0)) 
            }
            else {
                resi += 1
                res(resi)(0) = intervals(i)(0)
                res(resi)(1) = intervals(i)(1)
                
            }
        }
        
        return res.take(resi+1)
    }
}

源地址:57. 插入区间

问题描述:

给出一个无重叠的 ,按照区间起始端点排序的区间列表。

在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。

示例 1:

输入: intervals = [[1,3],[6,9]], newInterval = [2,5]
输出: [[1,5],[6,9]]
示例 2:

输入: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出: [[1,2],[3,10],[12,16]]
解释: 这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。

代码补充:

/**
方法一:利用五十六题的合并方法,先将newintervals与intervals合并,再对整个新数组进行合并区间
*/
object Solution {
    def insert(intervals: Array[Array[Int]], newInterval: Array[Int]): Array[Array[Int]] = {
        val length = intervals.length
        val tempArr = Array.ofDim[Int](length+1,2)
        for(i <- 0 to length-1) tempArr(i) = intervals(i)
        tempArr(length) = newInterval
        
        //merge func
        def merge(intervals: Array[Array[Int]]): Array[Array[Int]] = {
        val length = intervals.length
        if(length == 0 || length == 1) return intervals
        intervals.sortInPlaceBy{ a => a(0) }
        val res = Array.ofDim[Int](length,2)
        res(0)(0) = intervals(0)(0)
        res(0)(1) = intervals(0)(1)
        var resi = 0

        for( i <- 1 to length-1 ){
            if(res(resi)(1) >= intervals(i)(0) && res(resi)(0) <= intervals(i)(1)){
               res(resi)(1) = math.max(res(resi)(1), intervals(i)(1))
               res(resi)(0) = math.min(res(resi)(0), intervals(i)(0)) 
            }
            else {
                resi += 1
                res(resi)(0) = intervals(i)(0)
                res(resi)(1) = intervals(i)(1)
                
            }
        }
        return res.take(resi+1)
        }
        return merge(tempArr)
    }
}

/**
方法二基于贪婪法
由于intervals有序,先将无重叠的区间全部放入res中,即intervals(i)(1) < newStart
此时需要判断是否已经把intervals全部放入,若全部放入,将newIntervals放入数组尾部
否则此时一定发生了重叠情况,不断判断接下来的intervals中的区间是否与newIntervals重叠,而后再更新newIntervals,使用index记录intervals中不在更新的区间位置,将剩余的区间挂在res尾部即可
*/
import scala.collection.mutable
object Solution {
    def insert(intervals: Array[Array[Int]], newInterval: Array[Int]): Array[Array[Int]] = {
        val length = intervals.length
        val newStart = newInterval(0)
        val newEnd = newInterval(1)
        val res = new mutable.ArrayBuffer[Array[Int]]()
        var index = 0

        for(elem <- intervals if elem(1) < newStart){
            res += elem
            index += 1
        }

        if(index == length) res += newInterval
        else{
            //println(index)
            for(i <- index to length-1 if newInterval(1) >= intervals(i)(0)){
                newInterval(0) = math.min(newInterval(0), intervals(i)(0))
                newInterval(1) = math.max(newInterval(1), intervals(i)(1))
                index += 1
            }
            res += newInterval
            for(i <- index to length-1) res += intervals(i)
        }

        //println(index)
        return res.toArray
    }
}
posted @ 2020-07-11 23:09  ganshuoos  阅读(123)  评论(0编辑  收藏  举报