@@ -45,4 +45,97 @@ public double findMedianSortedArrays(int[] nums1, int[] nums2) {
45
45
return nums3 [n / 2 ];
46
46
}
47
47
}
48
+ }
49
+
50
+
51
+ /*
52
+ 双指针:遍历比较两个数组元素,根据奇偶个数找到整体中间位置,计算中位数
53
+ */
54
+ class Solution {
55
+ public double findMedianSortedArrays (int [] nums1 , int [] nums2 ) {
56
+ int m = nums1 .length , n = nums2 .length ;
57
+ int len = m + n ;
58
+ int left = -1 , right = - 1 ;
59
+ int index1 = 0 , index2 = 0 ;
60
+ for (int i = 0 ; i <= len / 2 ; i ++) {
61
+ left = right ;
62
+ if (index1 < m && (index2 >= n || nums1 [index1 ] < nums2 [index2 ])) {
63
+ right = nums1 [index1 ++];
64
+ } else {
65
+ right = nums2 [index2 ++];
66
+ }
67
+ }
68
+ if (len % 2 == 0 ) {
69
+ return (left + right ) / 2.0 ;
70
+ }
71
+ return right ;
72
+ }
73
+ }
74
+
75
+
76
+ /*
77
+ 二分查找:
78
+ 1、一个长度为 m 的数组,有 0 到 m 总共 m + 1 个位置可以切。我们把数组 A 和数组 B 分别在 i 和 j 进行切割
79
+ 2、将 i 的左边和 j 的左边组合成「左半部分」,将 i 的右边和 j 的右边组合成「右半部分」
80
+ 1)当 A 数组和 B 数组的总长度是偶数时,如果我们能够保证 左半部分的长度等于右半部分 i+j = m-i + n-j,也就是 j = (m+n)/2 - i,
81
+ 且左半部分最大的值小于等于右半部分最小的值,max(A[i-1],B[j-1])) <= min(A[i],B[j]))
82
+ 那么 中位数 = (左半部分最大值 + 右半部分最小值) / 2 = (max(A[i-1],B[j-1]) + min(A[i],B[j])) / 2
83
+ 2)当 A 数组和 B 数组的总长度是奇数时,如果我们能够保证 左半部分的长度比右半部分大 1, i+j = m-i + n-j + 1,也就是 j = (m+n+1)/2 - i,
84
+ 且左半部分最大的值小于等于右半部分最小的值,max(A[i-1],B[j-1])) <= min(A[i],B[j]))
85
+ 那么 中位数 = 左半部分最大值 = max(A[i-1],B[j-1])
86
+ 3、增加 i 的方式用二分,初始化 i 为中间的值,然后减半找中间的,直到找到答案
87
+ 4、时间复杂度:我们对较短的数组进行了二分查找,所以时间复杂度是 O(log(min(m,n))
88
+ 空间复杂度:只有一些固定的变量,和数组长度无关,所以空间复杂度是 O(1)
89
+
90
+ A: 2 4 6 | 8 10 12 14
91
+ iMin i iMax
92
+ B: 1 5 8 10 11 | 12 12 15
93
+ j
94
+ =================================
95
+ A: 2 4 6 8 10 | 12 14
96
+ iMin i iMax
97
+ B: 1 5 8 | 10 11 12 12 15
98
+ j
99
+ */
100
+ class Solution {
101
+ public double findMedianSortedArrays (int [] A , int [] B ) {
102
+ int m = A .length ;
103
+ int n = B .length ;
104
+ if (m > n ) {
105
+ return findMedianSortedArrays (B , A );
106
+ }
107
+ int iMin = 0 , iMax = m ;
108
+ while (iMin <= iMax ) {
109
+ int i = (iMin + iMax ) / 2 ;
110
+ int j = (m + n + 1 ) / 2 - i ;
111
+ if (j != 0 && i != m && B [j - 1 ] > A [i ]) {
112
+ iMin = i + 1 ;
113
+ } else if (i != 0 && j != n && A [i - 1 ] > B [j ]) {
114
+ iMax = i - 1 ;
115
+ } else {
116
+ int maxLeft = 0 ;
117
+ if (i == 0 ) {
118
+ maxLeft = B [j - 1 ];
119
+ } else if (j == 0 ) {
120
+ maxLeft = A [i - 1 ];
121
+ } else {
122
+ maxLeft = Math .max (A [i - 1 ], B [j - 1 ]);
123
+ }
124
+ if ((m + n ) % 2 == 1 ) {
125
+ return maxLeft ;
126
+ }
127
+
128
+ int minRight = 0 ;
129
+ if (i == m ) {
130
+ minRight = B [j ];
131
+ } else if (j == n ) {
132
+ minRight = A [i ];
133
+ } else {
134
+ minRight = Math .min (B [j ], A [i ]);
135
+ }
136
+ return (maxLeft + minRight ) / 2.0 ;
137
+ }
138
+ }
139
+ return 0.0 ;
140
+ }
48
141
}
0 commit comments