【LeetCode刷题笔记】排序

905. 按奇偶排序数组

解题思路:
  • 1)额外数组 + 两次遍历,第一遍将所有的 偶数 放到结果数组 res 的前面,第二遍将所有的 奇数 接着放到结果数组 res 后面。也可以使用 对撞指针 往结果数组里存,在 一次遍历 内搞定。
  • 2) 对撞指针 左边 不断的找到 第一个 奇数 右边 不断的找到第一个 偶数 ,找到就交换 左边 右边 。不断重复以上过程。原地算法,空间O(1)。

 ​​

解题思路: 

  • 3)快排二路分区逻辑,参考快排中分区交换的逻辑来处理,快排分区逻辑中是将比分区点小的交换到左边,将比分区点大的交换到右边,而本题可以认为是按奇偶性进行排序,将偶数交换到左边,将奇数交换到右边。

快排二路分区逻辑有两种版本,一种是使用对撞指针的版本,另一种是使用快慢指针的版本。

对撞指针的二路分区版本:

这个版本其实跟上面的方法 2)本质上是一样的。

快慢指针的二路分区版本: 

这个版本只能算是快排二路分区快慢指针版本的变形,并不是严格的分区逻辑。 

注意:本题与 [ 剑指 Offer 21.调整数组顺序使奇数位于偶数前面 ] 几乎雷同。

922. 按奇偶排序数组 II

解题思路:
  • 1) 额外数组 + 遍历原数组 ,将 偶数 放到新数组的偶数下标位置上 i = 0,i += 2 ,将 奇数 放到新数组的奇数下标位置   j = 1,j += 2。
  • 2 双指针 + 原地处理 指向偶数下标  i = 0   指向奇数下标  j = 1 ,遍历数组的每一个 偶数位 i += 2 如果在 偶数位 上发现一个 奇数 时,就不停的 while 尝试在 奇数位 上找到一个 偶数 j += 2 ,如果找到就交换二者swap(i, j)

注意 ij 的步长都要 + 2,因为奇偶下标都是间隔的。

88. 合并两个有序数组

解题思路:
  • 1) 额外数组,参考 归并排序 中合并两个有序数组的过程,设指针 i j  分别指向 nums1 nums2 ,然后比较二者 较小 的值存到 tmp 数组中,最后再将 tmp 数组拷贝到原数组。 空间O( m+n ) 时间 O(m+n)

不过题目中 nums1 预留了额外空间,很显然是要原地修改,而不是使用额外空间。

解题思路:
  • 2) 三指针逆向存取 ,设  i、 j、k  分别指向  nums1、 nums2、结果数组 的末尾, 遍历时从  nums1  nums2  屁股后面开始取值,谁 就把谁安排到 结果数组 的屁股后面(本题 结果数组 就是 nums1 )。 然后分别把较大的指针结果数组的指针 前移 一个。
  • 如果有一个取到空了,就把另一个剩余的全部逆序放入 nums1 中。
  • 循环条件是   nums1  nums2 的指针有一个没到头就继续 。 

当 nums1==nums2[j] 时,代码中取谁都无所谓,不会影响最终结果。 

56. 合并区间

解题思路:
  • 按照区间左端点升序排序 ,然后遍历所有的区间,依次比较 当前区间 与合并 结果集合 中的 前一个区间 是否有重叠,如果无重叠就直接把当前区间收集到结果集合中,如果有重叠就把当前区间合并到前一个区间中。
  • 判断 当前区间 前一个区间 是否有重叠的方法:
  • 前一个区间 右端点 <  当前区间 左端点 ,则 无重叠 前一个区间 右端点  > =  当前区间 左端点 ,则重叠 例如考虑左端点两个升序排列的两个区间 [a, b] [c, d] b < c 则无交集,若 b >= c 则有交集,如果有交集,则 交集的左边界 = a,  交集的 右边界 = max(b, d)

57. 插入区间

解题思路:
  • 1)观察 插入区间 原始区间 左右边界的关系 ,可得 不重叠 的条件是: 原区间.右 < 插入区间.左 原区间.左 > 插入区间.右
  • 先分别找出 重叠开始 结束 的区间索引,当然,也有可能插入的区间与所有原始区间都没有重叠(此时找不到重叠开始和结束的区间索引,记为-1)。
  • 我们可以分成以下两大类情况处理:
  • ①  插入区间与原始区间 有重叠 的情况,我们需要 合并重叠 的区域,然后按照 重叠之前、合并、重叠之后 的顺序添加区间。
  • ②  插入区间与原始区间 无重叠 的情况,就先直接添加 原始所有区间 ,并记录应该插入新区间的位置,最后再插入新区间即可。

 

这里如果 start == -1,则 end 一定也等于 -1,如果 start != -1,则 end 也一定不等于 -1,所以只需要是否重叠判断 start 是否为 -1 即可。

另外在无重叠情况下,查找插入位置,其实就是在一个有序数组中查找第一个比插入目标大的位置(因为题目给定的区间是已经按照左端点升序排序好了的),例如 1,2,3,7,9 中插入 5 我们应该找到 7 的位置,将 5 插入该位置,原来的 7 和 9 分别后移。

解题思路:

  • 2)分成三个阶段来考察
  • ① 先区间右边界 < 插入区间左边界 的区间放入到结果集,这些区间与插入区间无重叠
  • ② 将  区间左边界 ≤ 插入区间右边界 && 区间右边界 ≥ 插入区间左边界 的区间和插入区间进行合并,然后把合并的区间放入到结果集
  • ③ 将剩余的区间放入结果集,这些区间与插入区间无重叠

252. 会议室

解题思路:

  • 同56,只需要 判断区间是否有重叠 的即可,一旦有重叠的两个会议时间段,就不能全部参加了。 
  • 按照区间左端点升序排序 ,然后遍历所有的区间, 比较 [a, b] [c, d] 中是否有 b > c 的情况, 前一个会议 结束时间 大于 当前会议 开始时间 ,那么就冲突了。
  • 注意:本题中  b == c  是允许的,因为在前一个会议恰好结束时开始下一个会议是可以的。

253. 会议室 II

解题思路:
  • 1. 转化为公交车上下车问题 ,某个时刻上车 +1 人,某个时刻下车 -1 人,求车上最多有几人。题目要求的其实就是可在同一时刻进行的会议的最大数量。
  • 首先按照 [a, b] -> [[a, 1], [b, -1]]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

川峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值