day13:88. 合并两个有序数组、31. 下一个排列、4. 寻找两个正序数组的中位数

day13题目:88. 合并两个有序数组31. 下一个排列4. 寻找两个正序数组的中位数

学习计划链接:冲刺春招-精选笔面试 66 题大通关

今日知识点:数组、双指针、二分,难度为简单、中等、困难

昨日题目链接:冲刺春招-精选笔面试 66 题大通关 day12

给你两个按 非递减顺序 排列的整数数组 nums1nums2,另有两个整数 mn ,分别表示 nums1nums2 中的元素数目。

请你 合并 nums2 **到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意: 最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n

示例 1:

输入: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
解释: 需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

示例 2:

输入: nums1 = [1], m = 1, nums2 = [], n = 0
输出: [1]
解释: 需要合并 [1] 和 [] 。
合并结果是 [1] 。

示例 3:

提示:

  • nums1.length == m + n

  • nums2.length == n

  • 0 <= m, n <= 200

  • 1 <= m + n <= 200

  • -109 <= nums1[i], nums2[j] <= 109

进阶: 你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?

思路

显而易见的双指针

  • ij 分别指向nums1nums2最后一个元素,k指向合并后下标

  • 比较 nums1[i]nums2[j],谁大就将谁放至 nums1[k] 将其对应 ij 前移

  • 需注意的是当一轮循环结束后仍有 j >= 0 说明 nums2 中仍有元素未被合并,这个时候直接将其放入 nums1 即可

代码

整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。

  • 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3][1,3,2][3,1,2][2,3,1]

整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

  • 例如,arr = [1,2,3] 的下一个排列是 [1,3,2]

  • 类似地,arr = [2,3,1] 的下一个排列是 [3,1,2]

  • arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。

给你一个整数数组 nums ,找出 nums 的下一个排列。

必须 原地 修改,只允许使用额外常数空间。

示例 1:

示例 2:

示例 3:

提示:

  • 1 <= nums.length <= 100

  • 0 <= nums[i] <= 100

思路

  • 不讲武德版:调algorithm库里的全排列函数捏

  • 正经思路 没啥思路x屈服于题解了:

首先,下一个排列总是比当前排列要 ,除非该排列已经是最大的排列。所以我们需要找到一个 大于当前序列 的新序列,且 变大的幅度 尽可能 。具体地有:

  1. 将一个左边的 较小数 与一个右边的 较大数 交换,以能够让当前排列变大,从而得到下一个排列

  2. 同时这个 较小数 需要尽量 靠右,而 较大数 需要尽可能

  3. 交换完成后,较大数右边的数 需要 按照升序重新排列吗,这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。 具体地,我们这样描述该算法,对于长度为 n 的排列 a:

  4. 首先从后向前查找第一个顺序对 (i,i+1),满足 a[i] < a[i+1]。这样 较小数 即为 a[i]。此时 [i+1,n) 必然是下降序列

  5. 如果找到了顺序对,那么在区间 [i+1,n)从后向前 查找第一个元素 j ,满足 a[i] < a[j]。这样 较大数 即为 a[j]

  6. 交换 a[i]a[j],此时可以证明区间 [i+1,n) 必为 降序

  7. 接使用 双指针 反转区间 [i+1,n) 使其 变为升序

代码

给定两个大小分别为 mn 的正序(从小到大)数组 nums1nums2。请你找出并返回这两个正序数组的 中位数

算法的时间复杂度应该为 O(log (m+n))

示例 1:

示例 2:

提示:

  • nums1.length == m

  • nums2.length == n

  • 0 <= m <= 1000

  • 0 <= n <= 1000

  • 1 <= m + n <= 2000

  • -106 <= nums1[i], nums2[i] <= 106

思路

代码

思路一

最后更新于

这有帮助吗?