3-合并区间

1题目描述

在这里插入图片描述

2思路

  1. 在合并区间之前,需要对所有的区间按照区间第一个元素进行排序,这样可以保证已经合并的各个区间之后不会再包含其他区间,或者被其他区间包含;
    1. 首先自己进行一下排序练习,回顾冒泡排序和选择排序,详见3.1使用排序算法对区间进行排序
  2. 在合并时,核心思想就是:准备一个空的列表,每次合并都取列表中最后一个区间去和当前待加入的区间进行合并;因为区间已经排过序了,所以列表中非最后一个元素与当前待加入的区间肯定是没有重叠的;详见3.2合并区间

3实现

3.1使用排序算法对区间进行排序

Anchor1

  1. 冒泡排序和选择排序的动态执行过程详见:冒泡排序和选择排序_选择排序和冒泡排序-CSDN博客

3.1.1冒泡排序

  1. 核心思想:

    1. 两层循环:外层循环控制趟数,内层循环控制每一趟比较的次数;
    2. 两两比较,即时交换
  2. 应用到区间排序上,代码如下:

    from typing import List
    
    
    class Solution:
        def merge1(self, intervals: List[List[int]]) -> List[List[int]]:
            # 先排序,按照每个区间的左侧数值升序排序,使用冒泡排序
            # 外层循环控制排序的轮数
            for i in range(0, len(intervals) - 1):
                # 内层循环控制每一轮的比较次数
                for j in range(0, len(intervals) - 1 - i):
                    # 相邻元素两两比较,升序排列
                    if intervals[j][0] > intervals[j + 1][0]:
                        intervals[j], intervals[j + 1] = intervals[j + 1], intervals[j]
            print("冒泡排序结果:", intervals)
    # 主函数
    if __name__ == '__main__':
        # intervals = [[1,3],[2,6],[8,10],[15,18]]
        # intervals = [[1, 3], [8, 10], [15, 18], [2, 6]]
        intervals = [[1, 3], [16, 10], [15, 18], [2, 6]]
        solution = Solution()
        solution.merge1(intervals)
        
        # print(result)
    

    在这里插入图片描述

    在这里插入图片描述

3.1.2选择排序

  1. 核心思想:

    1. 两层循环:外层循环控制轮数(或者说固定住然后待比较的数),内层循环控制每一轮比较的次数(或者说控制当前参与比较的数)
    2. 每一轮,固定住某一个数,然后看之后的数是否比这个数大(小),如果是,则更新最大(小)的索引;最后完成交换;
  2. 应用到区间排序上,代码如下:

    from typing import List
    
    
    class Solution:
        def merge2(self, intervals: List[List[int]]) -> List[List[int]]:
            # 先排序,按照每个区间的左侧数值升序排序,使用选择排序
            for i in range(0, len(intervals) - 1):
                min_index = i  # 记录最小值的索引
                for j in range(i + 1, len(intervals)):
                    if intervals[j][0] < intervals[min_index][0]:
                        min_index = j  # 更新最小值的索引
                if min_index != i:
                    # 最小值不是当前i索引对应的值,交换
                    intervals[i], intervals[min_index] = intervals[min_index], intervals[i]
            print("选择排序结果:", intervals)
    
    
    # 主函数
    if __name__ == '__main__':
        # intervals = [[1,3],[2,6],[8,10],[15,18]]
        # intervals = [[1, 3], [8, 10], [15, 18], [2, 6]]
        # intervals = [[1, 3], [2, 10], [15, 18], [2, 6]]
        intervals = [[1, 3], [2, 5], [15, 18], [2, 6]]
        solution = Solution()
        solution.merge2(intervals)
        # print(result)
    
    

    在这里插入图片描述

    在这里插入图片描述

3.2合并区间

Anchor2

  1. 主要思路:准备一个空列表sorted_list,比较前一个区间的右侧数值和当前区间的左侧数值,如果前一个区间的右侧数值小于当前区间的左侧数值,则两个区间不重叠,直接添加进来;否则重叠,需要更新sorted_list中最后一个区间的右侧数值;

  2. 代码如下:

    from typing import List
    
    
    class Solution:
        def merge1(self, intervals: List[List[int]]) -> List[List[int]]:
            # 先排序,按照每个区间的左侧数值升序排序,使用冒泡排序
            # 外层循环控制排序的轮数
            for i in range(0, len(intervals) - 1):
                # 内层循环控制每一轮的比较次数
                for j in range(0, len(intervals) - 1 - i):
                    # 相邻元素两两比较,升序排列
                    if intervals[j][0] > intervals[j + 1][0]:
                        intervals[j], intervals[j + 1] = intervals[j + 1], intervals[j]
            print("冒泡排序结果:", intervals)
    
            # 合并区间
            sorted_list = []
            for item in intervals:
                # 空列表被视为False,非空列表被视为True
                if not sorted_list or sorted_list[-1][-1] < item[0]:
                    # 比较前一个区间的右侧数值和当前区间的左侧数值,如果前一个区间的右侧数值小于当前区间的左侧数值,则两个区间不重叠
                    sorted_list.append(item)
                else:
                    # 重叠则需要更新sorted_list中最后一个区间的右侧数值
                    sorted_list[-1][1] = max(sorted_list[-1][-1], item[1])
            return sorted_list
    
    
    # 主函数
    if __name__ == '__main__':
        # intervals = [[1,3],[2,6],[8,10],[15,18]]
        intervals = [[1, 3], [8, 10], [15, 18], [2, 6]]
        # intervals = [[1, 3], [2, 10], [15, 18], [2, 6]]
        # intervals = [[1, 3], [2, 5], [15, 18], [2, 6]]
        solution = Solution()
        sorted_list = solution.merge1(intervals)
        print("合并区间结果:", sorted_list)
        # solution.merge2(intervals)
        # print(result)
    
    
  3. 在力扣上执行,提示超出时间限制,可见这里使用冒泡排序的时候,两层循环的嵌套增加了算法的复杂度;

3.3排序算法修改

  1. 前面是自己实现了冒泡排序或者选择排序,其实python中的列表有封装好的排序算法
  1. 这里使用封装好的排序算法,即list中封装的sort函数:

    1. 只需执行:intervals.sort(key=lambda x: x[0]);key用于指定一个函数,这个函数会被应用到列表中的每一个元素上,获取用于排序的键;
    2. 关于此函数:

    在这里插入图片描述

  2. 因此,最终的合并区间的算法代码为:

    from typing import List
    
    
    class Solution:
        def merge1(self, intervals: List[List[int]]) -> List[List[int]]:
            # 先排序,按照每个区间的左侧数值升序排序
            intervals.sort(key=lambda x: x[0])
    
            # 合并区间
            sorted_list = []
            for item in intervals:
                # 空列表被视为False,非空列表被视为True
                if not sorted_list or sorted_list[-1][-1] < item[0]:
                    # 比较前一个区间的右侧数值和当前区间的左侧数值,如果前一个区间的右侧数值小于当前区间的左侧数值,则两个区间不重叠
                    sorted_list.append(item)
                else:
                    # 重叠则需要更新sorted_list中最后一个区间的右侧数值
                    sorted_list[-1][1] = max(sorted_list[-1][-1], item[1])
            return sorted_list
    
    
    # 主函数
    if __name__ == '__main__':
        # intervals = [[1,3],[2,6],[8,10],[15,18]]
        intervals = [[1, 3], [8, 10], [15, 18], [2, 6]]
        # intervals = [[1, 3], [2, 10], [15, 18], [2, 6]]
        # intervals = [[1, 3], [2, 5], [15, 18], [2, 6]]
        solution = Solution()
        sorted_list = solution.merge1(intervals)
        print("合并区间结果:", sorted_list)
        # solution.merge2(intervals)
        # print(result)
    
  3. 然后,就不会超出时间限制了:

    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值