Medium | LeetCode 34 | 剑指 Offer 53 - I. 在排序数组中查找数字 I | 二分法
剑指 Offer 53 - I. 在排序数组中查找数字 I
统计一个数字在排序数组中出现的次数。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
限制:
0 <= 数组长度 <= 50000
使用二分法分别找到最左边界和最右边界即可。二分法本质上是一种减法思想, 利用了数组有序的特性, 每次通过二分都能排除掉一半。
public int search(int[] nums, int target) {
if (nums.length == 0) {
return 0;
}
int fisrstPosition = findFirstPostion(nums, target);
if (fisrstPosition == -1) {
return 0;
}
int lastPosition = findLastPosition(nums, target);
return lastPosition - fisrstPosition + 1;
}
// 找target出现的最左边界
private int findFirstPostion(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
// 当mid值等于target值时, 当前mid的值也是还要保留的,
// 因为当前的mid值可能就是左边界, 也因此是要往左找
// 既然保留mid作为right, 所以取mid值, 一定是下取整
right = mid;
}
}
if (nums[left] != target) {
return -1;
}
return left;
}
// 找target出现的最右边界
private int findLastPosition(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = (left + right + 1) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
// 当mid值等于target值时, 当前mid的值也是还要保留的,
// 因为当前的mid值可能就是右边界, 也因此是要往右找
// 既然保留mid作为left, 所以取mid值, 一定是上取整
left = mid;
}
}
return left;
}