Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit40e1e49

Browse files
committed
update: update 004
1 parent90f64bd commit40e1e49

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

‎note/004/README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,27 @@ The median is (2 + 3)/2 = 2.5
2929

3030
##思路
3131

32-
题意是给你两个已排序的递增数组,让你找出其中位数,乍一看这题并不是很难,其实这题难度不可小觑,要做出时间复杂度为`O(log(m+n))` 的话需要了解从两个递增数组中找出第`k` 大的元素,也就是我写的`helper` 函数所起到的作用。下面来解释其原理:
32+
题意是给你两个已排序的递增数组,让你找出其中位数
3333

34-
假设数组分别记为 `A`,`B`,当前需要搜索第 `k` 大的数,于是我们可以考虑从数组 `A` 中取出前 `m` 个元素,从数组 `B` 中取出 `k - m` 个元素。由于数组 `A`,`B` 分别排序,则 `A[m]` 大于从数组 `A` 中取出的其他所有元素,`B[k - m]` 大于数组 `B` 中取出的其他所有元素。此时,尽管取出元素之间的相对大小关系不确定,但 `A[m]` 与 `B[k - m]` 的较大者一定是这 `k` 个元素中最大的。那么,较小的那个元素一定不是第 `k` 大的,它至多是第 `k - 1` 大的:因为它小于其他未被取出的所有元素,并且小于取出的 `k` 个元素中最大的那个。为叙述方便,假设 `A[m]` 是较小的那个元素。那么,我们可以进一步说,`A[1]`,`A[2]`...`A[m-1]` 也一定不是第 `k` 大的元素,因为它们小于 `A[m]`,而 `A[m]` 至多是第 `k - 1` 大的。因此,我们可以把较小元素所在数组中选出的所有元素统统排除,并且相应地减少 `k` 值。这样,我们就完成了一次范围缩小。特别地,我们可以选取 `m = k / 2`。而本题只是其一种情况而已,也就当总长为偶数时,找出其中间的两个数,相加除二即可;当总长为奇数时,找到中间的数即可。
34+
乍一看这题并不是很难,因为两序列有序,所以我们很容想到时间复杂度为`O(m + n)` 的做法,但这题要求的时间复杂度为`O(log(m + n))`,那么我们自然而然地就能想到二分查找法。
35+
36+
题目是让找两数组的中位数,我们可以泛化为求两数组中第`k` 大的元素,那么,求中位数就是其中的一个特例而已。`helper` 函数所起到的作用就是求两数组中第`k` 大的元素,下面来解释其原理:
37+
38+
假设数组分别记为`A``B`,当前需要搜索第`k` 大的数,于是我们可以考虑从数组`A` 中取出前`m` 个元素,从数组`B` 中取出`k - m` 个元素。由于数组`A``B` 分别排序,则`A[m - 1]` 大于从数组`A` 中取出的其他所有元素,`B[k - m - 1]` 大于数组`B` 中取出的其他所有元素。此时,尽管取出元素之间的相对大小关系不确定,但`A[m - 1]``B[k - m - 1]` 的较大者一定是这`k` 个元素中最大的。那么,较小的那个元素一定不是第`k` 大的,这里留给读者自己想象。
39+
40+
为叙述方便,假设`A[m - 1]` 是较小的那个元素,那么我们可以把`A[0]``A[1]`...`A[m - 1]` 排除掉,并且更新`k` 值为`k - m`,也就是下一次就是从剩余的元素中寻找第`k - m` 大的元素,这样,我们就完成了一次范围缩小,同理进行下一轮的操作。
41+
42+
那么什么时候停止操作呢?分两种情况:
43+
44+
1. 当某个数组的数都被取完了,那么直接返回另一个数组的后`k` 个元素即可。
45+
46+
2.`k = 1` 时,也就是只需再找一个数即可,也就是取两者当前较小的那个即可。
47+
48+
特别地,我们选取`m = k / 2`,下面是我画的草图,希望能帮助大家理解。
49+
50+
![](https://raw.githubusercontent.com/Blankj/awesome-java-leetcode/master/note/004/my_draw.jpg)
51+
52+
借助上面的理论,你能写出相关代码了吗?
3553

3654
```java
3755
classSolution {

‎note/004/my_draw.jpg

44.9 KB
Loading

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp