Open luna5210 opened 2 years ago
Tag : 双指针 中文链接:https://leetcode-cn.com/problems/merge-sorted-array/
题目描述: 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你合并 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 = [0], m = 0, nums2 = [1], n = 1 输出:[1] 解释:需要合并的数组是 [] 和 [1] 。 合并结果是 [1] 。 注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。 提示: nums1.length == m + n nums2.length == n 0 <= m, n <= 200 1 <= m + n <= 200 -10^9 <= nums1[i], nums2[j] <= 10^9 进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?
题目解答: 给定两个有序数组nums1、nums2,将两个数组合并到nums1,使其保证非递减顺序排序,nums1设计成m+n长度,不需要开拓新的空间。为了保证非递减排序,我们需要遍历数组,而指针正是用于遍历数组的,由于数组本身是有序的,所以从最后的大数来更新所需的步骤最少;那么这题两个数组各需要一个指针,nums1作为最后的返回数组,还需要一个指针pos(指向数组末尾m+n-1);另外两个指针分别指向nums1的m-1、nums2的n-1。 具体步骤:
注意:这里使用了++和--的小技巧,a++和++a都是将a加1,a++返回值为a,++a返回值为a+1。如果只是希望增加a的值而不是返回a的值,即本题中的移动指针,推荐使用++a,运行速度略快一些。 之前的一些for循环也是只需要增加a的值,但是有时需要注意for循环的结束条件。
代码:
class Solution { public: void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { int pos = m-- + n-- -1; while( m >= 0 && n >= 0){ nums1[pos--] = nums1[m] > nums2[n] ? nums1[m--] : nums2[n--]; } while( n >= 0){ nums1[pos--] = nums2[n--]; } } };
复杂度分析: 时间复杂度:O(m + n),需要遍历两个数组一次; 空间复杂度:O(1), 不需要额外使用空间。
Tag : 双指针 中文链接:https://leetcode-cn.com/problems/merge-sorted-array/
题目描述: 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你合并 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 = [0], m = 0, nums2 = [1], n = 1 输出:[1] 解释:需要合并的数组是 [] 和 [1] 。 合并结果是 [1] 。 注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。 提示: nums1.length == m + n nums2.length == n 0 <= m, n <= 200 1 <= m + n <= 200 -10^9 <= nums1[i], nums2[j] <= 10^9 进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?
题目解答: 给定两个有序数组nums1、nums2,将两个数组合并到nums1,使其保证非递减顺序排序,nums1设计成m+n长度,不需要开拓新的空间。为了保证非递减排序,我们需要遍历数组,而指针正是用于遍历数组的,由于数组本身是有序的,所以从最后的大数来更新所需的步骤最少;那么这题两个数组各需要一个指针,nums1作为最后的返回数组,还需要一个指针pos(指向数组末尾m+n-1);另外两个指针分别指向nums1的m-1、nums2的n-1。 具体步骤:
注意:这里使用了++和--的小技巧,a++和++a都是将a加1,a++返回值为a,++a返回值为a+1。如果只是希望增加a的值而不是返回a的值,即本题中的移动指针,推荐使用++a,运行速度略快一些。 之前的一些for循环也是只需要增加a的值,但是有时需要注意for循环的结束条件。
代码:
复杂度分析: 时间复杂度:O(m + n),需要遍历两个数组一次; 空间复杂度:O(1), 不需要额外使用空间。