合并两个有序的数组

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:

输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]
看到此题我们能想到的思路有两种:
1.因为nums1有足够的空间,所以直接将nums2放入nums1然后再进行排序。
代码如下:
方法一:
 1 void merge(int[] nums1, int m, int[] nums2, int n) {
 2         int i;
 3         int j;
 4         for(i=m+n-1,j=0;i>=m&&j<n;i--,j++){ //从后遍历nums1然后从后面倒着放nums2
 5                 nums1[i]=nums2[j];
 6         }
 7 
 8         int k;
 9         int l;
10         int tmp;
11         for(k=0;k<m+n-1;k++){ //冒泡排序
12             for(l=k+1;l<m+n;l++)
13                 if(nums1[k]>nums1[l]){
14                     tmp=nums1[k];
15                     nums1[k]=nums1[l];
16                     nums1[l]=tmp;
17                 }
18         }
22     }
23 public static void main(String[] args) {
24         int[] nums1 = new int[6];
25         int[] nums2 = new int[2];
26         nums1[0] = 1;
27         nums1[1] = 2;
28         nums1[2] = 3;
29         nums1[3] = 5;
30         nums2[0] = 2;
31         nums2[1] = 6;
32         merge(nums1,4,nums2,2);
33         for(int b = 0;b < nums1.length;b++) {
34             System.out.println(nums1[b]);
35        }
36    }

 

方法二:

 1 public static void merge(int[] nums1, int m, int[] nums2, int n) { 
 2         for(int i = 0;i < n;i++){ //拿着nums2的元素去插入
 3             int tem = nums2[i]; 
 4             int j = 0; 
 5             while(tem >= nums1[j] && j < m){ //若nums2得的元素大于nums1的元素
 6                 j++; //nums2往后移
 7             } 
 8             m++; //移向nums1的下一个元素
 9             for(int k = m - 1;k > j;k--){ 
10                 nums1[k] = nums1[k-1]; //nums1往后移
11             } 
12             nums1[j] = tem; //nums2放入当前找到的位子
13         } 
14     }
15     
16     public static void main(String[] args) {
17         int[] nums1 = {1,2,3,0,0,0};
18         int[] nums2 = {2,3,8};
19         
20         merge(nums1,3,nums2,3);
21         for(int k = 0;k < nums1.length;k++) {
22             System.out.println(nums1[k]);
23         }
24 
25     }

 

结果如下:

 

 

 

从上面的代码中我们可以看到先将nums2放入nums2,然后再排序。方法一相当与用了两次双重循环,时间复杂度是否优点大呢??而且这样是否浪费了题意呢??那再读一遍题给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。有没有更好一点解决办法呢?当然有:

2.我们先申请一个有m+n 大的数组,将nums1和nums2同时往新的数组里面放,因为他们都是有序的,所以就判断然后加就好了,这样就会避免双重循环给的复杂度太高,而且不“浪费题意”。我们看代码。

代码如下:

 方法三:

 1 void merge(int[] nums1, int m, int[] nums2, int n) {
 2         int[] nums = new int[m + n];//申请新的数组nums
 3         int index = 0;
 4         int i = 0;
 5         int j = 0;
 6         while (i < m && j < n ) { //两个数组同时判断
 7             if (nums1[i] <= nums2[j])
 8                 nums[index++] = nums1[i++];
 9             else 
10                 nums[index++] = nums2[j++];
11             
12         }
13         if ( i < m) { //这是为了nums1的长度比nums2大上面的while循环已经不能再判断。
14             while (i<m)
15                 nums[index++] = nums1[i++]; //nums2已经放完,直接将nums1剩下的往里面放
16         } 
17         if (j < n) {   //这是为了nums2的长度比nums1大上面的while循环已经不能再判断。
18             while (j<n)
19                 nums[index++] = nums2[j++];//nums1已经放完,直接将nums2剩下的往里面放
20         }
21         System.arraycopy(nums,0,nums1,0,nums.length - n); //给nums1赋去   
22     }
23   public static void main(String[] args) {
24        int[] nums1 = {1,2,3,0,0,0};
25        int[] nums2 = {2,3,8};
26      
27        merge(nums1,3,nums2,3);
28        for(int k = 0;k < nums1.length;k++) {
29            System.out.println(nums1[k]);
30      }
31  }

 结果如下:

 

从上面的代码中,我们可以看到它很巧妙的用到了nums1和nums2是有序的条件。而且最后也将最终的新的数组nums赋给了nums1也是实现了假定nums1有m+n大的空间,可以合并nums1和nums2了。

 

 
posted @ 2019-04-14 16:27  离愁i  阅读(714)  评论(0编辑  收藏  举报