day13:88. 合并两个有序数组、31. 下一个排列、4. 寻找两个正序数组的中位数
day13题目:88. 合并两个有序数组、31. 下一个排列、4. 寻找两个正序数组的中位数
学习计划链接:冲刺春招-精选笔面试 66 题大通关
今日知识点:数组、双指针、二分,难度为简单、中等、困难
昨日题目链接:冲刺春招-精选笔面试 66 题大通关 day12
给你两个按 非递减顺序 排列的整数数组 nums1
和 nums2
,另有两个整数 m
和 n
,分别表示 nums1
和 nums2
中的元素数目。
请你 合并 nums2
**到 nums1
中,使合并后的数组同样按 非递减顺序 排列。
注意: 最终,合并后数组不应由函数返回,而是存储在数组 nums1
中。为了应对这种情况,nums1
的初始长度为 m + n
,其中前 m
个元素表示应合并的元素,后 n
个元素为 0
,应忽略。nums2
的长度为 n
。
示例 1:
示例 2:
示例 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)
的算法解决此问题吗?
思路
显而易见的双指针
设
i
、j
分别指向nums1
、nums2
最后一个元素,k
指向合并后下标
比较
nums1[i]
和nums2[j]
,谁大就将谁放至nums1[k]
将其对应i
或j
前移
需注意的是当一轮循环结束后仍有
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屈服于题解了:
首先,下一个排列总是比当前排列要 大,除非该排列已经是最大的排列。所以我们需要找到一个 大于当前序列 的新序列,且 变大的幅度 尽可能 小。具体地有:
将一个左边的 较小数 与一个右边的 较大数 交换,以能够让当前排列变大,从而得到下一个排列
同时这个 较小数 需要尽量 靠右,而 较大数 需要尽可能 小
交换完成后,较大数右边的数 需要 按照升序重新排列吗,这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。 具体地,我们这样描述该算法,对于长度为 n 的排列 a:
首先从后向前查找第一个顺序对
(i,i+1)
,满足a[i] < a[i+1]
。这样 较小数 即为a[i]
。此时[i+1,n)
必然是下降序列。如果找到了顺序对,那么在区间
[i+1,n)
中 从后向前 查找第一个元素j
,满足a[i] < a[j]
。这样 较大数 即为a[j]
。交换
a[i]
与a[j]
,此时可以证明区间[i+1,n)
必为 降序。接使用 双指针 反转区间
[i+1,n)
使其 变为升序。
代码
给定两个大小分别为 m
和 n
的正序(从小到大)数组 nums1
和 nums2
。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 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
思路
思路1:按88. 合并两个有序数组中合并两个有序数组到
nums1
中后,直接找其中位数
代码
思路一
最后更新于