两个排序数组的中位数
标签:parse NPU mil code row amp new static min
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。
请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。
你可以假设 nums1 和 nums2 不同时为空。
示例 1:
nums1 = [1, 3] nums2 = [2]
中位数是 2.0
示例 2:
nums1 = [1, 2] nums2 = [3, 4]
中位数是 (2 + 3)/2 = 2.5
自我思路:
1.寻找出两个数组合并后中位数的位置
2.从小到大,从两个数组中取出对应位置的数
难点:
1.获取中位数的位置。本人对数字超级混乱,所以如何获取数组的中位数需要留意。
2.按元素大小,遍历两个有序数组的元素,并获取对应的中间的一个或两个数,从而获得中位数。
思路:从两个数组头部开始,比较元素大小,以A[m]和B[n]为例,则这两个长分别为m和n的数组的中位数位置应当是【(m+n-1)/2】或【(m+n-1)/2,(m+n-1)/2+1】。
(1)若A[0]>B[0],则合并后数组的第一个元素是B[0],反之则为A[0]。记为thisNum;
(2)以1中较大数继续与另一数组下一元素比较,获取thisNum。
(3)获取的thisNum是第【(m+n-1)/2】或【(m+n-1)/2,(m+n-1)/2+1】时,便记录下来求中位数。
3.从2的思路出发,可以实现算法的框架,但是会有一些细节问题:
(1)如何记录中位数的位数,是记录一个还是两个
(2)如何制定从小到大遍历数组的规则
算法实现:
1 import java.io.IOException;
2 import java.util.Arrays;
3 import java.util.Scanner;
4
5 public class MedianSortedArrays {
6 public static void main(String[] args) throws IOException{
7 /*获取输入内容*/
8 Scanner input = new Scanner(System.in);
9 System.out.println("请输入第一个数组,元素间以逗号隔开:");
10 int[] nums1=stringToArray(input.nextLine());
11 System.out.println("请输入第二个数组,元素间以逗号隔开:");
12 int[] nums2=stringToArray(input.nextLine());
13 System.out.println("这两个数组的中位数是:");
14 Solution getMedian=new Solution();
15 Arrays.sort(nums1);
16 Arrays.sort(nums2);
17 double median=getMedian.findMedianSortedArrays(nums1,nums2);
18 System.out.println(median);
19 }
20
21 /**
22 * 将获取的字符串转为数组
23 */
24 public static int[] stringToArray(String str){
25 String[] strArr= str.split(",");
26 int[] arr=new int[strArr.length];
27 for(int i=0;i){
28 arr[i]=Integer.parseInt(strArr[i].trim());
29 }
30 return arr;
31 }
32 }
33
34
35 class Solution {
36 public double findMedianSortedArrays(int[] nums1, int[] nums2) {
37 double midian;
38 int[] index=getIndex(nums1.length+nums2.length);
39 midian=getMedian(nums1,nums2,index);
40 return midian;
41 }
42
43 /**
44 * 获取中位数在组合后的数组中应当存在的位数
45 * @param arrLength
46 * @return
47 */
48 public int[] getIndex(int arrLength){
49 int[] index =new int[2];
50 index[0]=(arrLength-1)/2;//(数组长度-1)/2为中位数在有序数组中的下标之一
51 if(arrLength%2==0){ //当数组长度为偶数,则中位数是(数组长度-1)/2和(数组长度-1)/2+1这两个下标对应元素的平均值
52 index[1]=index[0]+1;
53 }
54 return index;
55 }
56
57 /**
58 * 获取中位数
59 * @param nums1
60 * @param nums2
61 * @param index 中位数下标对应数组[(数组长度-1)/2,(数组长度-1)/2+1]或[(数组长度-1)/2,0]
62 * @return
63 */
64 public double getMedian(int[] nums1, int[] nums2,int[] index){
65 double sum=0; //记录中位数对应下标两个元素之和
66 int maxIndex; //记录中位数下标数组的较大数
67 double indexLength;
68
69 /*此处获取中位数最大下标作为循环标记*/
70 if(index[1]==0){
71 maxIndex=index[0];
72 indexLength=1;
73 }else{
74 maxIndex=index[1];
75 indexLength=2;
76 }
77
78 /*获取两个数组中的对应下标元素之和*/
79 int j=0,k=0,thisIndex=0,thisNum = 0;
80 while(thisIndexmaxIndex){
81 if(j//当两个数组均可遍历时
82 if(nums1[j]>=nums2[k]){ //比较元素大小,当某一数组元素小,便推向该数组下一个元素
83 thisNum=nums2[k]; //记录比较所得的较小元素,作为thisNum
84 k++;
85 }else{
86 thisNum=nums1[j];
87 j++;
88 }
89 }else{ //当有数组遍历结束,但仍未找到中位数时
90 if(j==nums1.length){ //遍历完的数组不再参与thisNum的记录,只进行另外一个数组的遍历
91 thisNum=nums2[k];
92 k++;
93 }
94 if(k==nums2.length){
95 thisNum=nums1[j];
96 j++;
97 }
98 }
99
100 if(thisIndex==maxIndex){ //若遍历的次数达到中位数下标要求,便做和,记录中位数相关元素之和
101 sum+=thisNum;
102 }
103 if(index[1]!=0&&thisIndex==maxIndex-1){
104 sum+=thisNum;
105 }
106
107 thisIndex++; //遍历标记
108 }
109 return sum/indexLength; //返回中位数
110 }
111 }
本方案在leetCode提交后,结果运行时间为54ms,而LeetCode最快的结果是32ms
其代码如下
1 class Solution {
2 public double findMedianSortedArrays(int[] nums1, int[] nums2) {
3 int m = nums1.length, n = nums2.length, left = (m + n + 1) / 2, right = (m + n + 2) / 2;
4 return (findKth(nums1, nums2, left) + findKth(nums1, nums2, right)) / 2.0;
5 }
6 int findKth(int[] nums1, int[] nums2, int k) {
7 int m = nums1.length, n = nums2.length;
8 if (m > n) return findKth(nums2, nums1, k);
9 if (m == 0) return nums2[k - 1];
10 if (k == 1) return Math.min(nums1[0], nums2[0]);
11 int i = Math.min(m, k / 2), j = Math.min(n, k / 2);
12 if (nums1[i - 1] > nums2[j - 1]) {
13 return findKth(nums1, Arrays.copyOfRange(nums2, j, n), k - j);
14 } else {
15 return findKth(Arrays.copyOfRange(nums1, i, m), nums2, k - i);
16 }
17 }
18 }
通过比较可以看得出来,
1.对问题分析的深度和细致还不够,更偏向于暴力破解
2.对递归算法的运用是没有认识的
两个排序数组的中位数
标签:parse NPU mil code row amp new static min
原文地址:https://www.cnblogs.com/mudaoyuye/p/9537674.html
文章来自:
搜素材网的
编程语言模块,转载请注明文章出处。
文章标题:
两个排序数组的中位数
文章链接:http://soscw.com/index.php/essay/105236.html
评论