Skip to content

Commit c7afd46

Browse files
committed
Add solution 004 [Java]
1 parent 11f480c commit c7afd46

File tree

3 files changed

+150
-2
lines changed

3 files changed

+150
-2
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ Complete [solutions](https://github.com/doocs/leetcode/tree/master/solution) to
7777

7878
| # | Title | Tags |
7979
|---|---|---|
80+
| 004 | [Median of Two Sorted Arrays](https://github.com/doocs/leetcode/tree/master/solution/004.Median%20of%20Two%20Sorted%20Arrays) | `Array`, `Binary Search`, `Divide and Conquer` |
8081
| 023 | [Merge k Sorted Lists](https://github.com/doocs/leetcode/tree/master/solution/023.Merge%20k%20Sorted%20Lists) | `Linked List`, `Divide and Conquer`, `Heap` |
8182
| 032 | [Longest Valid Parentheses](https://github.com/doocs/leetcode/tree/master/solution/032.Longest%20Valid%20Parentheses) | `String`, `Dynamic Programming` |
8283
| 084 | [Largest Rectangle in Histogram](https://github.com/doocs/leetcode/tree/master/solution/084.Largest%20Rectangle%20in%20Histogram) | `Array`, `Stack` |
@@ -94,7 +95,7 @@ I'm looking for long-term contributors/partners to this repo! Send me [PRs](http
9495
" If you want to go fast, go alone. If you want to go far, go together. And that's the spirit of [teamwork](https://github.com/doocs/leetcode/graphs/contributors) ".
9596

9697
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
97-
| <center> [<img src="https://avatars3.githubusercontent.com/u/21008209?v=4" width="80px;"/>](https://github.com/yanglbme)<br />[💻](https://github.com/doocs/leetcode/commits?author=yanglbme "Code") </center> | <center> [<img src="https://avatars3.githubusercontent.com/u/23625436?v=4" width="80px;"/>](https://github.com/chakyam)<br />[💻](https://github.com/doocs/leetcode/commits?author=chakyam "Code") </center> | <center> [<img src="https://avatars3.githubusercontent.com/u/10081554?v=4" width="80px;"/>](https://github.com/zhkmxx9302013)<br />[💻](https://github.com/doocs/leetcode/commits?author=zhkmxx9302013 "Code") </center> | <center> [<img src="https://avatars3.githubusercontent.com/u/40383345?v=4" width="80px;"/>](https://github.com/MarkKuang1991)<br />[💻](https://github.com/doocs/leetcode/commits?author=MarkKuang1991 "Code") </center> | <center> [<img src="https://avatars3.githubusercontent.com/u/12371194?v=4" width="80px;"/>](https://github.com/fonxian)<br />[💻](https://github.com/doocs/leetcode/commits?author=fonxian "Code") </center> |
98-
|---|---|---|--|--|
98+
| <center> [<img src="https://avatars3.githubusercontent.com/u/21008209?v=4" width="80px;"/>](https://github.com/yanglbme)<br />[💻](https://github.com/doocs/leetcode/commits?author=yanglbme "Code") </center> | <center> [<img src="https://avatars3.githubusercontent.com/u/23625436?v=4" width="80px;"/>](https://github.com/chakyam)<br />[💻](https://github.com/doocs/leetcode/commits?author=chakyam "Code") </center> | <center> [<img src="https://avatars3.githubusercontent.com/u/10081554?v=4" width="80px;"/>](https://github.com/zhkmxx9302013)<br />[💻](https://github.com/doocs/leetcode/commits?author=zhkmxx9302013 "Code") </center> | <center> [<img src="https://avatars3.githubusercontent.com/u/40383345?v=4" width="80px;"/>](https://github.com/MarkKuang1991)<br />[💻](https://github.com/doocs/leetcode/commits?author=MarkKuang1991 "Code") </center> | <center> [<img src="https://avatars3.githubusercontent.com/u/12371194?v=4" width="80px;"/>](https://github.com/fonxian)<br />[💻](https://github.com/doocs/leetcode/commits?author=fonxian "Code") </center> | <center> [<img src="https://avatars3.githubusercontent.com/u/25222367?v=4" width="80px;"/>](https://github.com/zhanary)<br />[💻](https://github.com/doocs/leetcode/commits?author=zhanary "Code") </center> |
99+
|---|---|---|---|---|---|
99100

100101
<!-- ALL-CONTRIBUTORS-LIST:END -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
## 两个排序数组的中位数
2+
### 题目描述
3+
4+
给定两个大小为 m 和 n 的有序数组 **nums1****nums2**
5+
6+
请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。
7+
8+
你可以假设 **nums1****nums2** 不同时为空。
9+
10+
**示例 1:**
11+
```
12+
nums1 = [1, 3]
13+
nums2 = [2]
14+
15+
中位数是 2.0
16+
```
17+
18+
**示例 2:**
19+
```
20+
nums1 = [1, 2]
21+
nums2 = [3, 4]
22+
23+
中位数是 (2 + 3)/2 = 2.5
24+
```
25+
26+
### 解法
27+
假设两数组长度分别为 len1, len2,分别将 num1, num2 切成左右两半。
28+
举个栗子:
29+
30+
```
31+
nums1: num1[0] num1[1] num1[2]......num1[i - 1] | num1[i] ...nums1[len1 - 2] nums1[len1 - 1]
32+
33+
nums2: nums2[0] nums2[1] nums2[2]......nums2[j - 1] | nums2[j] ...nums2[len2 - 2] nums2[len2 - 1]
34+
35+
```
36+
num1 在[0, i - 1] 是左半部分,[i, len1 - 1] 是右半部分;
37+
num2 在[0, j - 1] 是左半部分,[j, len2 - 1] 是右半部分。
38+
39+
若两个左半部分合起来的最大值 `<=` 右半部分合起来的最小值。那么中位数就可以直接拿到了。
40+
41+
- 若 nums1[i - 1] > nums2[j],说明 num1 的左边有数据过大,应该放到右边,而这样会使左边总数少了,那么 num2 右边的一个给左边就平衡了。如下:
42+
```
43+
nums1: num1[0] num1[1] num1[2]......num1 | [i - 1] num1[i] ...nums1[len1 - 2] nums1[len1 - 1]
44+
45+
nums2: nums2[0] nums2[1] nums2[2]......nums2[j - 1] nums2[j] | ...nums2[len2 - 2] nums2[len2 - 1]
46+
```
47+
48+
- 若 nums2[j - 1] > nums1[i],同理。
49+
- 否则,计算中位数。
50+
51+
52+
```java
53+
class Solution {
54+
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
55+
int len1 = nums1.length;
56+
int len2 = nums2.length;
57+
58+
// 确保 len1 不大于 len2
59+
if (len1 > len2) {
60+
int[] tmp = nums1;
61+
nums1 = nums2;
62+
nums2 = tmp;
63+
int t = len1;
64+
len1 = len2;
65+
len2 = t;
66+
}
67+
68+
int min = 0;
69+
int max = len1;
70+
71+
int m = (len1 + len2 + 1) / 2;
72+
73+
while (min <= max) {
74+
int i = (min + max) / 2;
75+
76+
int j = m - i;
77+
78+
if (i > min && nums1[i - 1] > nums2[j]) {
79+
--max;
80+
} else if (i < max && nums2[j - 1] > nums1[i]) {
81+
++min;
82+
} else {
83+
84+
int maxLeft = i == 0 ? nums2[j - 1] : j == 0 ? nums1[i - 1] : Math.max(nums1[i - 1], nums2[j - 1]);
85+
86+
if (((len1 + len2) & 1) == 1) {
87+
return maxLeft;
88+
}
89+
90+
int minRight = i == len1 ? nums2[j] : j == len2 ? nums1[i] : Math.min(nums2[i], nums1[j]);
91+
92+
return (maxLeft + minRight) / 2.0;
93+
94+
}
95+
96+
}
97+
98+
return 0;
99+
}
100+
}
101+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
class Solution {
2+
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
3+
int len1 = nums1.length;
4+
int len2 = nums2.length;
5+
6+
if (len1 > len2) {
7+
int[] tmp = nums1;
8+
nums1 = nums2;
9+
nums2 = tmp;
10+
int t = len1;
11+
len1 = len2;
12+
len2 = t;
13+
}
14+
15+
int min = 0;
16+
int max = len1;
17+
18+
int m = (len1 + len2 + 1) / 2;
19+
20+
while (min <= max) {
21+
int i = (min + max) / 2;
22+
int j = m - i;
23+
24+
if (i > min && nums1[i - 1] > nums2[j]) {
25+
--max;
26+
} else if (i < max && nums2[j - 1] > nums1[i]) {
27+
++min;
28+
} else {
29+
30+
int maxLeft = i == 0 ? nums2[j - 1] : j == 0 ? nums1[i - 1] : Math.max(nums1[i - 1], nums2[j - 1]);
31+
32+
if (((len1 + len2) & 1) == 1) {
33+
return maxLeft;
34+
}
35+
36+
int minRight = i == len1 ? nums2[j] : j == len2 ? nums1[i] : Math.min(nums2[i], nums1[j]);
37+
38+
return (maxLeft + minRight) / 2.0;
39+
40+
}
41+
42+
}
43+
44+
return 0;
45+
}
46+
}

0 commit comments

Comments
 (0)