• 算法打卡day31|贪心算法篇05|Leetcode 435. 无重叠区间、763.划分字母区间、56. 合并区间


     算法题

    Leetcode 435. 无重叠区间

    题目链接:435. 无重叠区间

     大佬视频讲解:无重叠区间视频讲解

     个人思路

    和昨日的最少箭扎气球有些类似,先按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了

    解法
    贪心法

    首先区间1,2,3,4,5,6都按照右边界排好序

    取 区间1 右边界a和 区间2左边界b,如果区间a>b时,说明区间交叉,需要删除一个重叠区间,重新找右边界,取区间a和b中的最小右边界,继续往后遍历。若a

    总共区间个数为5,减去非交叉区间的个数3,移除区间的最小数量就是2。

    1. class Solution {
    2. public int eraseOverlapIntervals(int[][] intervals) {
    3. Arrays.sort(intervals, (a,b)-> {//按右边界排序
    4. return Integer.compare(a[0],b[0]);
    5. });
    6. int count = 1;
    7. for(int i = 1;i < intervals.length;i++){
    8. if(intervals[i][0] < intervals[i-1][1]){
    9. intervals[i][1] = Math.min(intervals[i - 1][1], intervals[i][1]);//选择小的右边
    10. continue;
    11. }else{
    12. count++;//非交叉区间数加1
    13. }
    14. }
    15. return intervals.length - count;//需要删除的区间数
    16. }
    17. }

    时间复杂度:O(n logN);(排序数组)

    空间复杂度:O( logN);(java所使用的内置函数用的是快速排序需要 logN 的空间)


     Leetcode  763.划分字母区间

    题目链接:763.划分字母区间

    大佬视频讲解:划分字母区间视频讲解

    个人思路

    这道题有些技巧,但这个技巧我不知道...

    解法
    贪心法

    在遍历的过程中相当于是要找每一个字母的边界,当找到之前遍历过的所有字母的最远边界,也就找到了分割点此时前面出现过所有字母,最远也就到这个边界了。

    所以步骤为

    1. 统计每一个字符最后出现的位置
    2. 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点

    1. class Solution {
    2. public List partitionLabels(String S) {
    3. List list = new LinkedList<>();
    4. int[] edge = new int[26];//边界数组
    5. char[] chars = S.toCharArray();//字符串转字符串数组
    6. for (int i = 0; i < chars.length; i++) {//更新字母的最远边界
    7. edge[chars[i] - 'a'] = i;
    8. }
    9. int idx = 0;
    10. int last = -1;
    11. for (int i = 0; i < chars.length; i++) {//遍历数组
    12. idx = Math.max(idx,edge[chars[i] - 'a']);
    13. if (i == idx) {//找到最远边界后分割,收集字符串长度
    14. list.add(i - last);
    15. last = i;
    16. }
    17. }
    18. return list;
    19. }
    20. }

    时间复杂度:O(n );(遍历数组)

    空间复杂度:O(1);(hash数组是固定大小)


     Leetcode  56. 合并区间

    题目链接:56. 合并区间

    大佬视频讲解:合并区间视频讲解

     个人思路

    这道题和无重叠区间,最少箭射气球 ,都是判断区间重叠。区别就是判断区间重叠后的逻辑,这道题是判断区间重叠后要进行区间合并,因此还是贪心先排序再处理

    解法
    贪心法

    先拿题目例子画个图 intervals = [[1,3],[2,6],[8,10],[15,18]]

    先按照左边界从小到大排序,然后如果 intervals[i][0] <= intervals[i - 1][1] 即intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠(本题相邻区间也算重爹,所以是<=)

    将重叠区间合并,合并后取最小左边界和最大右边界,作为一个新的区间,加入到result数组。如果没有合并就把原区间加入到result数组

    1. class Solution {
    2. public int[][] merge(int[][] intervals) {
    3. List<int[]> res = new LinkedList<>();
    4. Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));//按照左边界排序
    5. int start = intervals[0][0];//最小左边界
    6. int rightmost= intervals[0][1];//最大右边界
    7. for (int i = 1; i < intervals.length; i++) {
    8. //如果左边界大于最大右边界
    9. if (intervals[i][0] > rightmost) {
    10. res.add(new int[]{start, rightmost});//加入区间
    11. start = intervals[i][0];//更新start
    12. rightmost= intervals[i][1];
    13. } else {
    14. rightmost= Math.max(rightmost, intervals[i][1]);//更新最大右边界
    15. }
    16. }
    17. res.add(new int[]{start, rightmost});
    18. return res.toArray(new int[res.size()][]);
    19. }
    20. }

    时间复杂度:O(n logN);(排序数组)

    空间复杂度:O( logN);(java所使用的内置函数用的是快速排序需要 logN 的空间)


     以上是个人的思考反思与总结,若只想根据系列题刷,参考卡哥的网址代码随想录算法官网

  • 相关阅读:
    vue里el-form+el-table实现验证规则的写法
    NC26257 小雨坐地铁 分层图+虚拟源点
    [基础01]基础控件(上)-TextView-Button-EditText-ImageView
    Linux 系统为何产生大量的 core 文件?
    智慧水务:数字孪生污水处理厂,3D可视化一键管控
    【unaipp】tabBar配置/tabBar图标无法显示
    已解决 TypeError: Fetch argument None has invalid type <class ‘NoneType‘>
    短时间内带你图解 Kafka
    [更准确的倒计时功能]vue中使用web worker 实现倒计时
    JMeter笔记12 | JMeter集合点
  • 原文地址:https://blog.csdn.net/unstoppableyi/article/details/137150131