avatar

剑指Offer-在排序数组中查找数字

📝题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
统计一个数字在排序数组中出现的次数。

示例 1:

输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:

输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
 

限制:
· 0 <= 数组长度 <= 50000


📝思路

O(N)的做法人人都会,但对于一个排序数组而言,二分查找显然是能够有效降低时间复杂度的捷径。
利用二分法,找到target第一次出现和最后一次出现的位置,详细题解可参考《剑指Offer》第6.3节。
注意数组为空的情况。

📝题解

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
int getFirst(vector<int>& nums, int target, int left, int right) {
if (left > right) return -1;
int mid = (right + left) / 2;
if (nums[mid] == target) {
if (mid == 0 || mid > 0 && nums[mid-1] != target) {
return mid;
}
else return getFirst(nums, target, left, mid - 1);
}
else if (nums[mid] > target) {
return getFirst(nums, target, left, mid - 1);
}
else {
return getFirst(nums, target, mid + 1, right);
}
}

int getLast(vector<int>& nums, int target, int left, int right) {
if (left > right) return -1;
int mid = (right + left) / 2;
if (nums[mid] == target) {
if (mid == nums.size() - 1 || nums[mid+1] != target) {
return mid;
}
else return getLast(nums, target, mid + 1, right);
}
else if (nums[mid] > target) {
return getLast(nums, target, left, mid - 1);
}
else {
return getLast(nums, target, mid + 1, right);
}
}

int search(vector<int>& nums, int target) {
if (nums.size() < 1) return 0;
int left = getFirst(nums, target, 0, nums.size() - 1);
int right = getLast(nums, target, 0, nums.size() - 1);
if (left >= 0 && right >= 0) return right - left + 1;
return 0;
}
Author:WhiteBeerHouse
Link:https://github.com/WhiteBeerHouse/WhiteBeerHouse.github.io/tree/master/2021/03/12/%E5%89%91%E6%8C%87Offer-%E5%9C%A8%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E6%95%B0%E5%AD%97/
Copyright Notice:All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.