其他分享
首页 > 其他分享> > leetcode 给出一个无重叠的 ,按照区间起始端点排序的区间列表。

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

作者:互联网

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

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

示例 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] 重叠。

方法:贪心

贪心算法:
贪心算法一般用来解决需要 “找到要做某事的最小数量” 或 “找到在某些情况下适合的最大物品数量” 的问题,且提供的是无序的输入。

贪心算法的思想是每一步都选择最佳解决方案,最终获得全局最佳的解决方案。

标准解决方案具有 O(NlogN)\mathcal{O}(N \log N)O(NlogN) 的时间复杂度且由以下两部分组成:

如果输入数据本身有序,则我们不需要进行排序,那么该贪心算法具有 O(N)\mathcal{O}(N)O(N) 的时间复杂度。

如何证明你的贪心思想具有全局最优的效果:可以使用反证法来证明。

让我们来看下面的例子来理解:

在这里插入图片描述

我们可以分为三个步骤去实现它:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

算法:

class Solution:
    def insert(self, intervals: 'List[Interval]', newInterval: 'Interval') -> 'List[Interval]':
        # init data
        new_start, new_end = newInterval
        idx, n = 0, len(intervals)
        output = []
    <span class="hljs-comment"># add all intervals starting before newInterval</span>
    <span class="hljs-keyword">while</span> idx &lt; n <span class="hljs-keyword">and</span> new_start &gt; intervals[idx][<span class="hljs-number">0</span>]:
        output.append(intervals[idx])
        idx += <span class="hljs-number">1</span>
        
    <span class="hljs-comment"># add newInterval</span>
    <span class="hljs-comment"># if there is no overlap, just add the interval</span>
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> output <span class="hljs-keyword">or</span> output[<span class="hljs-number">-1</span>][<span class="hljs-number">1</span>] &lt; new_start:
        output.append(newInterval)
    <span class="hljs-comment"># if there is an overlap, merge with the last interval</span>
    <span class="hljs-keyword">else</span>:
        output[<span class="hljs-number">-1</span>][<span class="hljs-number">1</span>] = max(output[<span class="hljs-number">-1</span>][<span class="hljs-number">1</span>], new_end)
    
    <span class="hljs-comment"># add next intervals, merge with newInterval if needed</span>
    <span class="hljs-keyword">while</span> idx &lt; n:
        interval = intervals[idx]
        start, end = interval
        idx += <span class="hljs-number">1</span>
        <span class="hljs-comment"># if there is no overlap, just add an interval</span>
        <span class="hljs-keyword">if</span> output[<span class="hljs-number">-1</span>][<span class="hljs-number">1</span>] &lt; start:
            output.append(interval)
        <span class="hljs-comment"># if there is an overlap, merge with the last interval</span>
        <span class="hljs-keyword">else</span>:
            output[<span class="hljs-number">-1</span>][<span class="hljs-number">1</span>] = max(output[<span class="hljs-number">-1</span>][<span class="hljs-number">1</span>], end)
    <span class="hljs-keyword">return</span> output


class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
// init data
int newStart = newInterval[0], newEnd = newInterval[1];
int idx = 0, n = intervals.length;
LinkedList<int[]> output = new LinkedList<int[]>();

<span class="hljs-comment">// add all intervals starting before newInterval</span>
<span class="hljs-keyword">while</span> (idx &lt; n &amp;&amp; newStart &gt; intervals[idx][<span class="hljs-number">0</span>])
  output.add(intervals[idx++]);

<span class="hljs-comment">// add newInterval</span>
<span class="hljs-keyword">int</span>[] interval = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[<span class="hljs-number">2</span>];
<span class="hljs-comment">// if there is no overlap, just add the interval</span>
<span class="hljs-keyword">if</span> (output.isEmpty() || output.getLast()[<span class="hljs-number">1</span>] &lt; newStart)
  output.add(newInterval);
<span class="hljs-comment">// if there is an overlap, merge with the last interval</span>
<span class="hljs-keyword">else</span> {
  interval = output.removeLast();
  interval[<span class="hljs-number">1</span>] = Math.max(interval[<span class="hljs-number">1</span>], newEnd);
  output.add(interval);
}

<span class="hljs-comment">// add next intervals, merge with newInterval if needed</span>
<span class="hljs-keyword">while</span> (idx &lt; n) {
  interval = intervals[idx++];
  <span class="hljs-keyword">int</span> start = interval[<span class="hljs-number">0</span>], end = interval[<span class="hljs-number">1</span>];
  <span class="hljs-comment">// if there is no overlap, just add an interval</span>
  <span class="hljs-keyword">if</span> (output.getLast()[<span class="hljs-number">1</span>] &lt; start) output.add(interval);
  <span class="hljs-comment">// if there is an overlap, merge with the last interval</span>
  <span class="hljs-keyword">else</span> {
    interval = output.removeLast();
    interval[<span class="hljs-number">1</span>] = Math.max(interval[<span class="hljs-number">1</span>], end);
    output.add(interval);
  }
}
<span class="hljs-keyword">return</span> output.toArray(<span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[output.size()][<span class="hljs-number">2</span>]);

}
}

复杂度分析

标签:newInterval,idx,interval,add,intervals,端点,区间,output,leetcode
来源: https://www.cnblogs.com/2020javamianshiti/p/14474547.html