mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-10-31 02:53:42 +00:00
Update 53. 数字在排序数组中出现的次数.md
补充二分查找边界过程的配图,调整二分查找返回第一个大于等于目标值位置及计算次数的说明,精简右边界初始值取值的示例阐述。
This commit is contained in:
@@ -38,23 +38,11 @@ public int binarySearch(int[] nums, int K) {
|
||||
}
|
||||
```
|
||||
|
||||
但是在查找第一个位置时,找到元素之后应该继续往前找。也就是当 nums[m]\>=k 时,在左区间继续查找,左区间应该包含 m 位置。
|
||||
但是在查找第一个位置时,找到元素之后应该继续往前找。也就是当 nums[m]\>=k 时,在左区间继续查找,左区间应该包含 m 位置。这样 binarySearch 返回的是第一个大于等于 k 的位置。
|
||||
|
||||
```java
|
||||
private int binarySearch(int[] nums, int target) {
|
||||
int l = 0, h = nums.length;
|
||||
while (l < h) {
|
||||
int m = l + (h - l) / 2;
|
||||
if (nums[m] >= target)
|
||||
h = m;
|
||||
else
|
||||
l = m + 1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
```
|
||||
查找最后一个位置可以转换成寻找 k+1 的第一个位置,并再往前移动一个位置,因此出现次数为 binarySearch(k + 1) - binarySearch(k)。以题目中的数组为例,查找区间为左闭右开的 [l, h):
|
||||
|
||||
查找最后一个位置可以转换成寻找 k+1 的第一个位置,并再往前移动一个位置。
|
||||
<div align="center"> <img src="pics/offer53-lower-bound.png" width="680px"/> </div><br>
|
||||
|
||||
```java
|
||||
public int countTarget(int[] scores, int target) {
|
||||
@@ -76,10 +64,4 @@ private int binarySearch(int[] nums, int target) {
|
||||
}
|
||||
```
|
||||
|
||||
需要注意以上实现的查找第一个位置的 binarySearch 方法,h 的初始值为 nums.length,而不是 nums.length - 1。先看以下示例:
|
||||
|
||||
```text
|
||||
nums = [2,2], k = 2
|
||||
```
|
||||
|
||||
如果 h 的取值为 nums.length - 1,那么在查找最后一个位置时,binarySearch(nums, k + 1) - 1 = 1 - 1 = 0。这是因为 binarySearch 只会返回 [0, nums.length - 1] 范围的值,而 binarySearch([2,2], 3) 应该返回 3 插入 nums 中的位置,也就是数组最后一个位置再往后一个位置,即 nums.length。所以需要将 h 取值为 nums.length,从而使得 binarySearch 返回的区间更大,能够覆盖 k 大于 nums 最后一个元素的情况。
|
||||
需要注意 binarySearch 中 h 的初始值为 nums.length,而不是 nums.length - 1。k 比所有元素都大时,第一个大于等于 k 的位置在数组之外,应该返回 nums.length。例如 nums = [2, 2]、k = 2 时,binarySearch(nums, 3) 应返回 2,次数为 2 - 0 = 2;如果 h 从 nums.length - 1 开始,返回值最大只能是 1,得到的次数就变成了 1。
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
Reference in New Issue
Block a user