leetcode-no4

本文只要使用两种解法解决两个有序数组O(m+n)时间复杂度查找其中位数的算法。
  • 解法一:遍历合并数组
    因为两个数组都是遍历的,所以通过遍历比较大的数组比较两个数组的值,直到其值为两个数组之和的一半下标为止

  • 解法二:分治算法
    此算法是对第一种算法的优化,采用分治算法的思想,结合二分法进行中位值查找


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/** 
* Copyright,ShanNong Inc,2018 and onwards
*
* Author:fanghua fan
*/
package com.fanghua.algorithm.divideandconquer;

/**
* leetcode
* <p>
* 4. Median of Two Sorted Arrays
* <p>
* There are two sorted arrays nums1 and nums2 of size m and n respectively.
* <p>
* Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
* <p>
* Example 1:
* nums1 = [1, 3]
* nums2 = [2]
* <p>
* The median is 2.0
* Example 2:
* nums1 = [1, 2]
* nums2 = [3, 4]
* <p>
* The median is (2 + 3)/2 = 2.5
*/
public class SolutionNum4 {
/**
* 1、因为两个数组都是遍历的,所以通过遍历比较大的数
* 组比较两个数组的值,直到其值为两个数组之和的一半下标为止
*
* @param nums1
* @param nums2
* @return 中位值
*/
public static double findMedianToIterator(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
int allLen = len1 + len2;
int[] temp = (len1 > len2) ? nums1 : nums2;
int arrayFlag = 0;// 判断当前遍历最后一个数是哪个数组
for (int index1 = 0, index2 = 0; ; ) {
// 中位值判断
if (index1 + index2 == allLen / 2) {
int left = 0;
if (index1 - 1 >= 0 && arrayFlag == 1) {
left = nums1[index1 - 1];
} else if (index2 - 1 >= 0 && arrayFlag == 2) {
left = nums2[index2 - 1];
}
int right = Math.min(len1 == 0 ? Integer.MAX_VALUE : (index1 >= len1 ? nums2[index2] : nums1[index1]),
len2 == 0 ? Integer.MAX_VALUE : (index2 >= len2 ? nums1[index1] : nums2[index2]));
if (allLen % 2 == 1) {
return (right) / 1.0;
} else {
return (left + right) / 2.0;
}
}
// 值判断
if (len2 == 0 || index2 >= len2
|| (len1 != 0 && index1 < len1 && nums1[index1] < nums2[index2])) {
index1++;// 第一个数组指针向后移动
arrayFlag = 1;
} else {
index2++;
arrayFlag = 2;
}
}
}

/**
* 2、此算法是对第一种算法的优化,采用分治算法的思想,结合二分法进行中位值查找
*
* @param nums1
* @param nums2
* @return
*/
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n = nums1.length;
int m = nums2.length;
if (n > m) { //保证数组1一定最短
return findMedianSortedArrays(nums2, nums1);
}
int L1 = 0, L2 = 0, R1 = 0, R2 = 0, c1, c2, lo = 0, hi = 2 * n;
while (lo <= hi) { //二分
c1 = (lo + hi) / 2; //c1是二分的结果
c2 = m + n - c1;
L1 = (c1 == 0) ? Integer.MIN_VALUE : nums1[(c1 - 1) / 2]; //map to original element
R1 = (c1 == 2 * n) ? Integer.MAX_VALUE : nums1[c1 / 2];
L2 = (c2 == 0) ? Integer.MIN_VALUE : nums2[(c2 - 1) / 2];
R2 = (c2 == 2 * m) ? Integer.MAX_VALUE : nums2[c2 / 2];

if (L1 > R2) {
hi = c1 - 1;
} else if (L2 > R1) {
lo = c1 + 1;
} else {
break;
}
}
return (Math.max(L1, L2) + Math.min(R1, R2)) / 2.0;
}
}

(全文完)3/25/2018 8:57:58 PM