Leetcode 88合并两个有序数组
500 Words|Read in about 2 Min|本文总阅读量次
leetcode第88题,合并两个有序数组。采用双指针的算法来完成。
Leetcode 88合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
示例 1:
1输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
2输出:[1,2,2,3,5,6]
3解释:需要合并 [1,2,3] 和 [2,5,6] 。
4合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
示例 2:
1输入:nums1 = [1], m = 1, nums2 = [], n = 0
2输出:[1]
3解释:需要合并 [1] 和 [] 。
4合并结果是 [1] 。
示例 3:
1输入:nums1 = [0], m = 0, nums2 = [1], n = 1
2输出:[1]
3解释:需要合并的数组是 [] 和 [1] 。
4合并结果是 [1] 。
5注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。
提示:
nums1.length==m+nnums2.length==n- 0 <=
m,n<= 200 - 1 <=
m+n<= 200 - -109 <=
nums1[i],nums2[j]<= 109
**进阶:**你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?
思路
可以直接利用函数的快速排序。
- 将
nums2的元素放到nums1中,形成一个新的只有nums1的序列 - 然后对
nums的序列快速排序
解题
1class Solution {
2 //合并成一个数组,然后快速排序
3 public void merge(int[] nums1, int m, int[] nums2, int n) {
4 for(int i = 0; i < n; i++)
5 {
6 nums1[m + i] = nums2[i];
7 }
8 Arrays.sort(nums1);
9 }
10}
其实还可以利用递增的关系(双指针)
- 每个数组头部头有一个指针指向第一位,创建一个临时数组
- 比较双指针所在的值,会出现三种结果。如果相等,默认取
nums2的元素,并且指针往后移动一位;如果不相等,取指针指向小的那位,并且指针往后移动一位。 - 直到两个指针全部移动完成
1class Solution {
2 //双指针做法,增加一个临时数组
3 public void merge(int[] nums1, int m, int[] nums2, int n) {
4 int k = m + n;
5 int[] tmp = new int[k];
6 for(int index = 0, nums1Index = 0, nums2Index = 0; index < k; index++)
7 {
8 if(nums1Index >= m)//nums1数组元素取完
9 {
10 tmp[index] = nums2[nums2Index++];
11 }else if(nums2Index >= n)//nums2数组元素取完
12 {
13 tmp[index] = nums1[nums1Index++];
14 }else if(nums1[nums1Index] < nums2[nums2Index])
15 //nums1元素小于nums2元素
16 {
17 tmp[index] = nums1[nums1Index++];
18 }else//nums2元素小于nums1元素
19 {
20 tmp[index] = nums2[nums2Index++];
21 }
22 }
23 //重新赋值给nums1
24 for(int i = 0; i < k; i++)
25 {
26 nums1[i] = tmp[i];
27 }
28 }
29
30}
由于这里nums1存在一个m+n的元素存放,那么其实可以利用上这个空间,不需要临时tmp数组
还是利用双指针做法
- 每个数组头尾部有一个指针指向最后一位
- 比较双指针所在的值,会出现三种结果。如果相等,默认取
nums2的元素,并且指针往前移动一位;如果不相等,取指针指向大的那位,并且指针往前移动一位。把元素存放到nums1的数组中 - 直到两个指针全部移动完成
1class Solution {
2 //双指针做法,利用nums1的空间,从后往前降序排列
3 public void merge(int[] nums1, int m, int[] nums2, int n) {
4 int k = m + n;
5 for(int index = k-1, nums1Index = m - 1, nums2Index = n -1;
6 index >= 0; index--)
7 {
8 if(nums1Index < 0)//nums1元素已经取完
9 {
10 nums1[index] = nums2[nums2Index--];
11 }else if(nums2Index < 0)//nums2元素已经取完
12 {
13 break;
14 }else if(nums1[nums1Index] > nums2[nums2Index])
15 //nums1元素值大于nums2,取nums1值
16 {
17 nums1[index] = nums1[nums1Index--];
18 }else
19 {
20 //nums2元素值大于等于nums1,取nums2值
21 nums1[index] = nums2[nums2Index--];
22 }
23 }
24 }
25
26}