leetcode-pp / 91alg-5-daily-check

91 天学算法第五期打卡
55 stars 14 forks source link

【Day 66 】2021-11-14 - 435. 无重叠区间 #85

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

435. 无重叠区间

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/non-overlapping-intervals/

前置知识

暂无

题目描述

给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

注意:

可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
示例 1:

输入: [ [1,2], [2,3], [3,4], [1,3] ]

输出: 1

解释: 移除 [1,3] 后,剩下的区间没有重叠。
示例 2:

输入: [ [1,2], [1,2], [1,2] ]

输出: 2

解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
示例 3:

输入: [ [1,2], [2,3] ]

输出: 0

解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
florenzliu commented 2 years ago

Explanation

Code

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if len(intervals) == 0:
            return 0

        intervals.sort()
        ans = 1

        def lenOfLIS(l):
            d = []
            for start, end in l:
                i = bisect.bisect_left(d, end)
                if i < len(d):
                    d[i] = end
                elif not d or d[-1] <= start:
                    d.append(end)
            return len(d)

        return len(intervals) - lenOfLIS(intervals)

Complexity

fzzfgbw commented 2 years ago

思路

贪心

代码

class Solution {

        public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 0) {
            return 0;
        }

        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[1] - interval2[1];
            }
        });

        int n = intervals.length;
        int ans = 1;
        int r = intervals[0][1];
        for (int i = 1; i < n; ++i) {
            if(intervals[i][0]>=r){
                r = intervals[i][1];
                ans++;
            }
        }
        return n - ans;
    }

}

复杂度分析

jiahui-z commented 2 years ago

思路: since the start of an interval must be smaller or equal to the end of the interval, sort all intervals by each start (or end, both works), then iterate through the input array and record the number of non-overlapping intervals

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        // sort the intervals based on its end, increasing order
        Arrays.sort(intervals, Comparator.comparingInt(interval -> interval[0]));

        int start = intervals[intervals.length-1][0];
        // the number of non-overlapping intervals
        int count = 1;
        for (int i = intervals.length - 1; i >= 0; i--) {
            int[] interval = intervals[i];
            // non-overlapping case
            if (interval[1] <= start) {
                start = interval[0];
                count++;
            }
        }

        return intervals.length - count;
    }
}

Time Complexity: O(nlogn) Space Complexity: O(1)

falconruo commented 2 years ago

思路: 贪心, 本题求最小移除的重叠区间, 可转化为求最多保留的不重叠区间数,按照右边界排序,比较连续两个区间,前面一个区间的右边界和相邻后面一个区间的左边界不重叠则保留,最后将总的区间数-最大保留的区间数

复杂度分析:

代码(C++):

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int n = intervals.size();
        if (n == 0) return 0;

        sort(intervals.begin(), intervals.end(), 
             [](const vector<int>& a, const vector<int>& b) { return a[1] < b[1]; }
            );

        int curR = intervals[0][1];

        int maxKeep = 1;
        for (int i = 1; i < n; ++i) {
            if (intervals[i][0] >= curR) {
                maxKeep++;
                curR = intervals[i][1];
            }
        }

        return n - maxKeep;
    }
};
LareinaWei commented 2 years ago

Thinking

Greedy. First sort the array by starting time, go through the array, if we find an overlap, remove the one with bigger end time.

Code

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        intervals.sort()
        start = float(-inf)
        count = 0
        for i in intervals:
            if i[0] >= start:
                start = i[1]
            else:
                count += 1
                start = min(start, i[1])
        return count
Laurence-try commented 2 years ago

思路

Greedy approach by ending point

代码

使用语言:Python3

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if len(intervals) == 0:
            return 0
        intervals.sort()
        end = intervals[0][1]
        pointer = 0
        count = 0
        for i in range(1, len(intervals)):
            if intervals[pointer][1] > intervals[i][0]:
                if intervals[pointer][1] > intervals[i][1]:
                    pointer = i
                count += 1
            else:
                pointer = i
        return count

复杂度分析 时间复杂度:O(nlogn) 空间复杂度:O(1)

HouHao1998 commented 2 years ago

思想

代码

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 0) {
            return 0;
        }

        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[0] - interval2[0];
            }
        });

        int n = intervals.length;
        int[] f = new int[n];
        Arrays.fill(f, 1);
        for (int i = 1; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                if (intervals[j][1] <= intervals[i][0]) {
                    f[i] = Math.max(f[i], f[j] + 1);
                }
            }
        }
        return n - Arrays.stream(f).max().getAsInt();
    }
}

复杂度分析

时间复杂度:O(nlogn) 空间复杂度:O(1)

BpointA commented 2 years ago

思路

排序+贪心

代码

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        lens={}
        starts=[]
        ends=[]
        s=0
        alls=0
        for i in intervals:
            tp=tuple(i)
            len=i[1]-i[0]
            lens[tp]=i[1]
            starts.append(i[0])
            ends.append(i[1])
            alls+=1

        l=sorted(lens.items(),key=lambda x:x[1])

        min_val=min(starts)
        s=max(ends)-min_val+1
        zeros=[0]*s
        c=0
        for i in l:
            x=i[0][0]
            y=i[0][1]
            lst=zeros[x-min_val:y-min_val]
            if 1 not in lst:
                c+=1
                for j in range(x,y):

                    t=j-min_val
                    zeros[t]=1

        return alls-c
ZJP1483469269 commented 2 years ago

思路

排序+贪心

代码

 class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if(intervals.length <= 1) return 0;
        Arrays.sort(intervals , (a , b) ->{
            return a[1] - b[1];
        });
        int end = intervals[0][1];
        int sum = 1;
        for(int i = 1 ;i < intervals.length ; i++){
            if(intervals[i][0] >= end){
                sum++;
                end = intervals[i][1];
            }
        }
        return intervals.length - sum;
    }
}

复杂度分析:

时间复杂度:O(nlogn) 空间复杂度:O(1)

zszs97 commented 2 years ago

开始刷题

题目简介

【Day 66 】2021-11-14 - 435. 无重叠区间

题目思路

题目代码

代码块

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if (intervals.empty()) {
            return 0;
        }

        sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) {
            return u[1] < v[1];
        });

        int n = intervals.size();
        int right = intervals[0][1];
        int ans = 1;
        for (int i = 1; i < n; ++i) {
            if (intervals[i][0] >= right) {
                ++ans;
                right = intervals[i][1];
            }
        }
        return n - ans;
    }
};

复杂度

taoyr722 commented 2 years ago

代码

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if not intervals:
            return 0
        nums = sorted(intervals, key=lambda x:x[1])
        count = 1    
        end = nums[0][1]
        for st, en in nums:
            if st >= end:
                count += 1
                end = en
        return len(nums) - count
Zhi22 commented 2 years ago

class Solution: def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int: if not intervals: return 0 nums = sorted(intervals, key=lambda x:x[1]) count = 1
end = nums[0][1] for st, en in nums: if st >= end: count += 1 end = en return len(nums) - count

muimi commented 2 years ago

思路

贪心

代码

class Solution {
  public int eraseOverlapIntervals(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
    int end = intervals[0][1], remove = 0;
    for (int i = 1; i < intervals.length; i++) {
      if (intervals[i][0] < end) {
        remove++;
        end = Math.min(end, intervals[i][1]);
      } else {
        end = intervals[i][1];
      }
    }
    return remove;
  }
}
class Solution {
  public int eraseOverlapIntervals(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
    int end = intervals[0][1], count = 1;
    for (int i = 1; i < intervals.length; i++) {
      if (intervals[i][0] >= end) {
        count++;
        end = intervals[i][1];
      }
    }
    return intervals.length - count;
  }
}

复杂度

ymkymk commented 2 years ago

class Solution { public int eraseOverlapIntervals(int[][] intervals) { if (intervals.length == 0) { return 0; }

    Arrays.sort(intervals, new Comparator<int[]>() {
        public int compare(int[] interval1, int[] interval2) {
            return interval1[0] - interval2[0];
        }
    });

    int n = intervals.length;
    int[] f = new int[n];
    Arrays.fill(f, 1);
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < i; ++j) {
            if (intervals[j][1] <= intervals[i][0]) {
                f[i] = Math.max(f[i], f[j] + 1);
            }
        }
    }
    return n - Arrays.stream(f).max().getAsInt();
}

}

guangsizhongbin commented 2 years ago
func eraseOverlapIntervals(intervals [][]int) int {
    // 本身为空,需要移除0个
    n := len(intervals)
    if n == 0{
        return 0
    }

    // 根据第二维进行排序, 从小到大
    sort.Slice(intervals, func(i, j int) bool{ return intervals[i][1] < intervals[j][1]})
    ans, right := 1, intervals[0][1]
    for _, p := range intervals[1:]{
        if p[0] >= right {
            ans++
            right = p[1]
        }
    }
    return n - ans
}
chaggle commented 2 years ago

title: "Day 67 435. 无重叠区间" date: 2021-11-14T20:25:06+08:00 tags: ["Leetcode", "c++", "Greed"] categories: ["91-day-algorithm"] draft: true


435. 无重叠区间

题目

给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

注意:

可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
示例 1:

输入: [ [1,2], [2,3], [3,4], [1,3] ]

输出: 1

解释: 移除 [1,3] 后,剩下的区间没有重叠。
示例 2:

输入: [ [1,2], [1,2], [1,2] ]

输出: 2

解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
示例 3:

输入: [ [1,2], [2,3] ]

输出: 0

解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

题目思路

  • 1、单刀直入,按照右边界排序,值越大越在后面,而后按照每一个子vector元素的右边界值与失分产生重叠来删除区间即可
class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int n = intervals.size();
        if(n == 0) return n;
        sort(intervals.begin(), intervals.end(), [](const auto & a, const auto &b)
        {
            return a[1] < b[1];
        });
        int del = 0;
        int r = intervals[0][1];
        for(int i = 1; i < n; i++)
        {
            if(intervals[i][0] < r) del++;
            else r = intervals[i][1];
        }
        return del;
    }
};

复杂度

HWFrankFung commented 2 years ago

Codes

var eraseOverlapIntervals = function(intervals) {
    if(intervals.length === 0) return 0;

    intervals.sort((interval1, interval2) => {
        return parseInt(interval1[1]) - parseInt(interval2[1]);
    });

    let interval = intervals[0];
    const res = [interval];
    for(let i = 1; i < intervals.length; i++) {
        if(intervals[i][0] >= interval[1]) {
            res.push(intervals[i]);
            interval = intervals[i];
        } 
    }

    return intervals.length - res.length;
};
yj9676 commented 2 years ago
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 0) {
            return 0;
        }

        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[0] - interval2[0];
            }
        });

        int n = intervals.length;
        int[] f = new int[n];
        Arrays.fill(f, 1);
        for (int i = 1; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                if (intervals[j][1] <= intervals[i][0]) {
                    f[i] = Math.max(f[i], f[j] + 1);
                }
            }
        }
        return n - Arrays.stream(f).max().getAsInt();
    }
}
m-z-w commented 2 years ago
var eraseOverlapIntervals = function(intervals) {
    let ans = 1
    intervals.sort((a, b) => a[1] - b[1])
    let right = intervals[0][1]
    for (let i = 1; i < intervals.length; i++) {
        const interval = intervals[i]
        if (interval[0] >= right) {
            ans++
            right = interval[1]
        }
    }
    return intervals.length - ans
};

空间:O(logn) 排序所使用的栈空间 时间:O(nlogn) 排序的时间复杂度

BreezePython commented 2 years ago

思路

排序后双指针比较

代码

class Solution:
    def eraseOverlapIntervals(self, intervals):
        ln = len(intervals)
        if ln < 2:
            return 0
        intervals = sorted(intervals, key=lambda x: (x[1], x[0]))
        ret = 0
        left = 0
        for right in range(1, ln):
            if intervals[right][0] < intervals[left][1]:
                ret += 1
            else:
                left = right
        return ret

复杂度

mokrs commented 2 years ago
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
    if (intervals.size() == 0) {
        return 0;
    }

    //按结束时间从小到大排序
    sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) {
        return a[1] < b[1];
    });

    int end = intervals[0][1];
    int res = 1;
    for (int i = 1; i < intervals.size(); ++i) {
        if (intervals[i][0] >= end) {
            ++res;
            end = intervals[i][1];
        }
    }

    return intervals.size() - res;
}
JK1452470209 commented 2 years ago

思路

dp

代码

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 0) {
            return 0;
        }

        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[0] - interval2[0];
            }
        });

        int n = intervals.length;
        int[] f = new int[n];
        Arrays.fill(f, 1);
        for (int i = 1; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                if (intervals[j][1] <= intervals[i][0]) {
                    f[i] = Math.max(f[i], f[j] + 1);
                }
            }
        }
        return n - Arrays.stream(f).max().getAsInt();
    }
}

复杂度

时间复杂度:O(nlogn)

空间复杂度:O(1)

brainlds commented 2 years ago

class Solution { public int eraseOverlapIntervals(int[][] intervals) { Arrays.sort(intervals, (a, b) -> a[1] - b[1]); int end = intervals[0][1], count = 1; for (int i = 1; i < intervals.length; i++) { if (intervals[i][0] >= end) { count++; end = intervals[i][1]; } } return intervals.length - count; } }

asterqian commented 2 years ago

思路

贪心算法,先对数组进行排序,注意应该用结束时间来排,因为如果按开始时间,可能整个区间会非常大没有办法得到正确答案。但用结束时间进行排序的话,如果pre_end比curr_start要大,证明现在的这个区间会重复不能要,直接不做任何处理到下一个,反之区间就增长并且把pre_end更新成为curr_end的值,最后返回n-不重复的区间长度。

代码

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b) {
            return a[1] < b[1];
        });
        int r = intervals[0][1];
        int noOverlap = 1;
        for (int i = 1; i < intervals.size(); ++i) {
            if (intervals[i][0] >= r) {
                noOverlap++;
                r = intervals[i][1];
            }
        }
        return intervals.size() - noOverlap;
    }
};
时间复杂度 O(nlogn)
空间复杂度 O(1)
Tomtao626 commented 2 years ago

思路

import ( "fmt" "sort" )

func eraseOverlapIntervals(intervals [][]int) int { var flag int sort.Slice(intervals, func(i, j int) bool { return intervals[i][0] < intervals[j][0] }) fmt.Println(intervals) for i:=1;i<len(intervals);i++{ if intervals[i-1][1]>intervals[i][0]{ flag++ intervals[i][1] = min(intervals[i-1][1],intervals[i][1]) } } return flag } func min(a,b int)int{ if a > b{ return b } return a }


## 复杂度
+ > 时间:O(nlogn)
+ > 空间:O(1)
last-Battle commented 2 years ago

思路

关键点

代码

c Code:


class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if (intervals.empty()) {
            return 0;
        }

        sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) {
            if (a[1] != b[1]) {
                return (a[1] < b[1]);
            } else {
                return (a[0] < b[0]);
            }
        });

        int res = 0;
        vector<int> pre = intervals[0];
        for (int i = 1; i < intervals.size(); ++i) {
            if (pre[1] > intervals[i][0]) {
                ++res;
            } else {
                pre = intervals[i];
            }
        }

        return res;
    }
};

复杂度分析

令 n 为数组长度。

wangwiitao commented 2 years ago
var eraseOverlapIntervals = function(intervals) {
    intervals.sort((a, b) => {
        return a[1] - b[1]
    })

    let count = 1
    let end = intervals[0][1]

    for(let i = 1; i < intervals.length; i++) {
        let interval = intervals[i]
        if(interval[0] >= end) {
            end = interval[1]
            count += 1
        }
    }

    return intervals.length - count
};
freedom0123 commented 2 years ago
class Solution {
public:
    // 按照区间右边界排序
    static bool cmp (const vector<int>& a, const vector<int>& b) {
        return a[1] < b[1];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if (intervals.size() == 0) return 0;
        sort(intervals.begin(), intervals.end(), cmp);
        int count = 1; // 记录非交叉区间的个数
        int end = intervals[0][1]; // 记录区间分割点
        for (int i = 1; i < intervals.size(); i++) {
            if (end <= intervals[i][0]) {
                end = intervals[i][1];
                count++;
            }
        }
        return intervals.size() - count;
    }
};
carterrr commented 2 years ago
class 无重叠区间_435 {
    public int eraseOverlapIntervals(int[][] intervals) {
        // 想找最少删除的  转化为能放下最多的LIS
        // 按照右边界排序  始终找左边界比右边界大的下一个 能让右边界最小
        Arrays.sort(intervals, Comparator.comparingInt(a -> a[1]));
        int end = intervals[0][1];
        int count = 1;
        for(int i = 1; i < intervals.length; i++) {
            if(end <= intervals[i][0]) {
                end = intervals[i][1];
                count ++;
            }
        }
        return intervals.length - count;
    }
}
chakochako commented 2 years ago
class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if not intervals:
            return 0

        intervals.sort(key=lambda x: x[1])
        n = len(intervals)
        right = intervals[0][1]
        ans = 1

        for i in range(1, n):
            if intervals[i][0] >= right:
                ans += 1
                right = intervals[i][1]

        return n - ans
user1689 commented 2 years ago

题目

https://leetcode-cn.com/problems/non-overlapping-intervals/

思路

Greedy

python3

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:

        intervals.sort(key=lambda x: x[1])
        # print(intervals)
        count = 0
        i = 0
        while(i < len(intervals)):
            count += 1
            j = i + 1
            while (j < len(intervals) and intervals[j][0] < intervals[i][1]):
                j += 1
            i = j
        return len(intervals) - count

# Greedy 
# 1.Sweeping line / diff
# 2.Sort
#  sort by starting point => the minimum number of intervals to cover the whole
#  sort by ending point => the maximum number of intervals that are non-overlapping
# Dp
# 

复杂度分析

相关题目

  1. https://leetcode-cn.com/problems/maximum-length-of-pair-chain/
KennethAlgol commented 2 years ago

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals == null || intervals.length <= 1) return 0;
        Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
        int count = 1;
        int[] interval = intervals[0];

        for (int i = 1; i < intervals.length; i++){
            if (intervals[i][0] >= interval[1]){
                count++;
                interval = intervals[i];
            }
        }
        return intervals.length - count;
    }
}
WeiWri-CC commented 2 years ago
class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if not intervals:
            return 0

        intervals.sort(key=lambda x : x[1])
        n = len(intervals)
        ans = 1
        right = intervals[0][1]

        for i in range(1, n):
            if right <= intervals[i][0]:
                ans += 1
                right = intervals[i][1]

        return n - ans
falsity commented 2 years ago
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 0) {
            return 0;
        }

        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[1] - interval2[1];
            }
        });

        int n = intervals.length;
        int right = intervals[0][1];
        int ans = 1;
        for (int i = 1; i < n; ++i) {
            if (intervals[i][0] >= right) {
                ++ans;
                right = intervals[i][1];
            }
        }
        return n - ans;
    }
}
yibenxiao commented 2 years ago

【Day 66】435. 无重叠区间

思路

贪心

代码

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if (intervals.empty()) {
            return 0;
        }

        sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) {
            return u[1] < v[1];
        });

        int n = intervals.size();
        int right = intervals[0][1];
        int ans = 1;
        for (int i = 1; i < n; ++i) {
            if (intervals[i][0] >= right) {
                ++ans;
                right = intervals[i][1];
            }
        }
        return n - ans;
    }
};

复杂度

时间复杂度:O(nlogn)

空间复杂度:O(logn)

Auto-SK commented 2 years ago

思路

贪心法

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if not intervals:
            return 0
        intervals.sort(key=lambda x: x[1])
        n = len(intervals)
        right = intervals[0][1]
        ans = 1
        for i in range(1, n):
            if intervals[i][0] >= right:
                ans += 1
                right = intervals[i][1]
        return n - ans

复杂度

CruiseYuGH commented 2 years ago

思路

关键点

代码

Python3 Code:


class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if not intervals:
            return 
        n = len(intervals)
        intervals.sort(key=lambda x:x[1])
        right = intervals[0][1]
        ans =1
        for i in range(1,n):
            if intervals[i][0] >=right:
                ans+=1
                right = intervals[i][1]
        return n-ans 

复杂度分析

令 n 为数组长度。

Zhang6260 commented 2 years ago

JAVA版本

思路:主要使用贪心,对原始数据进行重新排序(这是是对区间的结束进行排序的),第一执行完就记录其结束的时间,然后取下一个区间的开始时间与之比较,如果开始时间大于上一个的结束时间,则计数+1,反之则更新结束时间。

class Solution {
   public int eraseOverlapIntervals(int[][] intervals) {
       PriorityQueue<int[]> queue =new PriorityQueue<>(new Comparator<int[]>() {
           @Override
           public int compare(int[] o1, int[] o2) {
               return o1[1]-o2[1];
           }
       });
       for(int i[]:intervals){
           queue.add(i);
       }
       int res =0;
       int end =0;
       end=queue.peek()[0];
       while (!queue.isEmpty()){
           int temo[] = queue.poll();
           if(temo[0]>=end){
               end=temo[1];
           }else{
               res++;
           }
       }
       return res;
   }
}

时间复杂度:O(nlog n)//排序算法的时间复杂度

空间复杂度:O(n)

L-SUI commented 2 years ago

var eraseOverlapIntervals = function(intervals) { if (!intervals.length) { return 0; }

intervals.sort((a, b) => a[1] - b[1]);

const n = intervals.length;
let right = intervals[0][1];
let ans = 1;
for (let i = 1; i < n; ++i) {
    if (intervals[i][0] >= right) {
        ++ans;
        right = intervals[i][1];
    }
}
return n - ans;

};

V-Enzo commented 2 years ago

思路

  1. 主要是能够将问题转化为求保留最多多少个区间。
  2. 对所有元素的右边界进行排序,然后遍历每个元素的右边值是否小于下一个的左边值。
  3. 主要还是运用了贪心思想。
    class Solution {
    public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        auto cmp = [](vector<int>& v1, vector<int>& v2)
        {
            return v1[1] < v2[1];
        };
        if(intervals.empty()) return 0;
        sort(intervals.begin(), intervals.end(), cmp);
        int  N = intervals.size();
        int maxRemain = 1;
        int curRight = intervals[0][1];
        for(int i=1; i<N; i++)
        {
            if(intervals[i][0] >= curRight)
            {
                maxRemain++;
                curRight = intervals[i][1];
            }
        }
        return N-maxRemain;
    }
    };

    Complexity:

    Space:O(n) TIme:O(nlogn)

15691894985 commented 2 years ago
  1. 无重叠区间

https://leetcode-cn.com/problems/non-overlapping-intervals/

剩下的相邻区间前面区间的结束和后面区间的开始是一个非严格递增序列

最长上升子序列的解法:https://leetcode-cn.com/problems/non-overlapping-intervals/solution/chuan-shang-yi-fu-wo-jiu-bu-ren-shi-ni-liao-lai-2/

    class Solution:
        def lengthLIS(self,A:List[int])-> int:
            d = []
            for s,e in A:
                i = bisect.bisect_left(d,e)
                if i < len(d):
                    d[i] = e
                elif not d or d[-1]<=s:
                    d.append(e)
            return len(d)
        def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
            n = len(intervals)
            if n==0:return 0
            ans = 1
            intervals.sort(key = lambda a:a[0])#对开始序列排序
            return n-self.lengthLIS(intervals)

直接贪心:贪心的选择下一个区间起点大于上一个终点的区间,没有就跳过

    class Solution:
        def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
            if not intervals:
                return 0

            intervals.sort(key=lambda x: x[1])
            n = len(intervals)
            right = intervals[0][1]
            ans = 1

            for i in range(1, n):
                if intervals[i][0] >= right:
                    ans += 1
                    right = intervals[i][1]

            return n - ans

时间复杂度分析:

Richard-LYF commented 2 years ago

class Solution: def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int: if not intervals: return 0

    intervals.sort()
    n = len(intervals)
    f = [1]

    for i in range(1, n):
        f.append(max((f[j] for j in range(i) if intervals[j][1] <= intervals[i][0]), default=0) + 1)

    return n - max(f)
biscuit279 commented 2 years ago

思路

class Solution:
    def lengthOfLIS(self, A: List[int]) -> int:
        d = []
        for s, e in A:
            i = bisect.bisect_left(d, e)
            if i < len(d):
                d[i] = e
            elif not d or d[-1] <= s:
                d.append(e)
        return len(d)
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        n = len(intervals)
        if n == 0: return 0
        ans = 1
        intervals.sort(key=lambda a: a[0])
        return n - self.lengthOfLIS(intervals)

时间复杂度:O(nlogn) 空间复杂度:O(n)

for123s commented 2 years ago

代码

C++ Code:

class Solution {
public:
    static bool cmp(vector<int> a, vector<int> b)
    {
        if(a[0]==b[0])
            return a[1]<b[1];
        return a[0]<b[0];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if(intervals.size()==0)
            return 0;
        sort(intervals.begin(),intervals.end(),cmp);
        int right = intervals[0][1];
        int res = 0;
        for(int i=1;i<intervals.size();++i)
        {
            if(right<=intervals[i][0])
                right = intervals[i][1];
            else if(right>intervals[i][0]&&right<=intervals[i][1])
                ++res;
            else if(right>intervals[i][1])
            {
                ++res;
                right = intervals[i][1];
            }
        }
        return res;
    }
};
lihuiwen commented 2 years ago

代码

class Solution {
public:
    static bool cmp(vector<int> a, vector<int> b)
    {
        if(a[0]==b[0])
            return a[1]<b[1];
        return a[0]<b[0];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if(intervals.size()==0)
            return 0;
        sort(intervals.begin(),intervals.end(),cmp);
        int right = intervals[0][1];
        int res = 0;
        for(int i=1;i<intervals.size();++i)
        {
            if(right<=intervals[i][0])
                right = intervals[i][1];
            else if(right>intervals[i][0]&&right<=intervals[i][1])
                ++res;
            else if(right>intervals[i][1])
            {
                ++res;
                right = intervals[i][1];
            }
        }
        return res;
    }
};
joriscai commented 2 years ago

思路

代码

javascript

/*
 * @lc app=leetcode.cn id=435 lang=javascript
 *
 * [435] 无重叠区间
 */

// @lc code=start
/**
 * @param {number[][]} intervals
 * @return {number}
 */
var eraseOverlapIntervals = function(intervals) {
  if (!intervals.length) {
    return 0
  }

  // 由于区间的起点总是小于终点
  // 根据区间的终点排序
  // 按照右边界排序,从左到右遍历,这样选择的空间最小,留给下个空间最大,
  // 从而移除的更少
  intervals.sort((a, b) => a[1] - b[1])

  const n = intervals.length
  // 先取第一个区间
  let right = intervals[0][1]
  let ans = 1
  // 从第二个区间开始比较
  for (let i = 1; i < n; i++) {
    const left = intervals[i][0]
    // 若当前的起点比上一个区间的终点都大,则说明两个区间不重叠了
    if (left >= right) {
      ++ans
      right = intervals[i][1]
    }
  }

  // 最终总的减去符合题意的,则为需要移除的
  return n - ans
};
// @lc code=end

复杂度分析

Moin-Jer commented 2 years ago

思路


贪心

代码


class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> {return a[1] - b[1];});
        int end = intervals[0][1];
        int count = 1;
        for (int i = 1; i < intervals.length; ++i) {
            if (intervals[i][0] >= end) {
                end = intervals[i][1];
                ++count;
            }
        }
        return intervals.length - count;
    }
}

复杂度分析


ZETAVI commented 2 years ago
public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> a[1] == b[1] ? b[0] - a[0] : a[1] - b[1]);
        int end = Integer.MIN_VALUE, count = 0;
        for (int[] cur : intervals) {
            if (cur[0] >= end) {
                count++;
                end = cur[1];
            }
        }
        return intervals.length - count;
    }

复杂度分析

时间复杂度:O(NlogN) 空间复杂度:O(1)

skinnyh commented 2 years ago

Note

Solution

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        intervals.sort(key=lambda x: x[1])
        end, res = float('-inf'), 0
        for t in intervals:
            if t[0] < end:
                # remove the interval
                res += 1
            else:
                end = t[1]
        return res

Time complexity: O(NlogN)

Space complexity: O(1)

taojin1992 commented 2 years ago

Understand:

1 <= intervals.length <= 2 * 10^4
intervals[i].length == 2
-2 * 10^4 <= starti < endi <= 2 * 10^4

intervals = [[1,2],[2,3],[3,4],[1,3]]

intervals = [[1,2],[1,3],[2,3],[3,4]]

|.    |
     |.  |

cur.end > next.start

|.      |
|.    |

keep the interval whose end is smaller

|.      |
 |.    |

|.      |
  |.    |

Plan & Match:

- edge case: one interval

- sort by start
- one for loop, compare cur with the next, keep a counter

for (int next = 1; next < intervals.length; next++) {
    if (intervals[cur][1] > intervals[next][0]) {
        // keep whose end is smaller
        count++;
        if (intervals[cur][1] >= intervals[next][1]) {
            // keep next, remove cur
            cur = next;
        } 
    }
    else {
        cur = next;
    }
}

note to change the syntax

Review:

Input: intervals = [[1,2],[2,3],[3,4],[1,3]]
Output: 1

intervals = [[1,2],[1,3],[2,3],[3,4]]

Input: intervals = [[1,2],[1,2],[1,2]]
Output: 2

intervals = [[1,2],[1,2],[1,2]]

***Input: 
[[0,2],[1,3],[2,4],[3,5],[4,6]]
  cur.   n                       count = 1
  cur.         n
  cur.               n

Evaluate:

n = intervals.length

Time: O(nlogn) + O(n) = O(nlogn)
Space: O(1)

Code:

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 1) return 0;
        Arrays.sort(intervals, (a, b) -> (a[0] - b[0]));
        int cur = 0;
        int count = 0;
        for (int next = 1; next < intervals.length; next++) {
            if (intervals[cur][1] > intervals[next][0]) {
                // keep whose end is smaller
                count++;
                if (intervals[cur][1] >= intervals[next][1]) {
                    // keep next, remove cur
                    cur = next;
                } 
            }
            else {
                cur = next; // note this line
            }
        }

        return count;
    }
}