//统计一个数字在排序数组中出现的次数。
//
//
//
// 示例 1:
//
// 输入: nums = [5,7,7,8,8,10], target = 8
//输出: 2
//
// 示例 2:
//
// 输入: nums = [5,7,7,8,8,10], target = 6
//输出: 0
//
//
//
// 限制:
//
// 0 <= 数组长度 <= 50000
//
//
//
// 注意:本题与主站 34 题相同(仅返回值不同):https://leetcode-cn.com/problems/find-first-and-last-
//position-of-element-in-sorted-array/
// Related Topics 数组 二分查找
// 👍 85 👎 0
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int search(int[] nums, int target) {
// //今天刷题开始有一点感觉了,刷题还是应该按照分类来刷,按照详细分类,如leetcode总结如下
// //1.二分查找 2.二叉树、链表 3.递归、DFS 4.双指针 4.BFS、拓扑排序 6.hash表 7.动态规划 8.滑动窗口 9.字典树
// //备注:先按照分类刷剑指offer,掌握不牢靠再刷top100和面试精选
// //这个题是一个典型的二分查找,我的思路先定位到那个数字然后,收缩低位和高位指针,计算多少个数字,无奈,时间太慢
// int low = 0;int res = 0;int high = nums.length - 1;
// while(low < high){
// int mid = (low + high)/2;
// if(nums[mid] < target){
// low = mid + 1;
// }else if(nums[mid] > target){
// high = mid - 1;
// }else{
// //如果命中,先结果集+1,然后收缩低位、高位指针
// res++;
// low = mid - 1;
// high = mid + 1;
// //当无论哪一个低位、高位所对应的元素不是目标结果时,就退出循环,最后返回结果集
// while(nums[low] == target || nums[high] == target){
// if(nums[low] == target){
// low--;
// res++;
// }
// if(nums[high] == target){
// high++;
// res++;
// }
// }
// }
// }
// return res;//最坏时间复杂度就是,数组中元素全部相等,O(nlogn),感觉还不如,遍历一遍暴力解法
//哎,官方解释,大佬还是大佬,官方解释是寻找目标数字数组的前后两个指针指向的位置,相减即可
//二分查找的题,太坑了,很不容易写完全正确,需要考虑左右开闭空间,同时考虑while循环判断条件都是相等的情况,高低位指针赋值也需要考虑
int low = 0;int high = nums.length - 1;
//找右边界
while(low <= high){
int mid = (high - low)/2 + low;
if(nums[mid] <= target){
low = mid + 1;
}else if(nums[mid] > target){
high = mid - 1;
}
}
int right = low;
//注意这里如果有边界的前一个数不是target则提前返回,这里的作用是找不到直接减少第二次二分查找
if(high >= 0 && nums[high] != target) return 0;
//找左边界
// int i = 0;int j = nums.length - 1;//这里可以优化,不需要再开一个高低位指针,且高位指针不需要重置,减少一次二分
// while(i <= j){
// int k = (j - i)/2 + i;
// if(nums[k] < target){
// i = k + 1;
// }else if(nums[k] >= target){
// j = k - 1;
// }
// }
// int left = j;
low = 0;//这里可以优化,不需要再开一个高、低位指针,且高位指针不需要重置,减少一次二分
while(low <= high){
int mid = (high - low)/2 + low;
if(nums[mid] < target){
low = mid + 1;
}else if(nums[mid] >= target){
high = mid - 1;
}
}
int left = high;
return right - left - 1;
//时间复杂度为O(logn)
}
}
(剑指offer 53-1 在排序数组中查找数字1)2021.1-10
最新推荐文章于 2022-11-19 09:13:11 发布