【问题描述】[中等]

统计一个数字在排序数组中出现的次数。
示例 1:输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:输入: nums = [5,7,7,8,8,10], target = 6
输出: 0

【解答思路】

1. 暴力法/遍历

时间复杂度:O(N) 空间复杂度:O(1)

  public int search(int[] nums, int target) {int count = 0;for(int num : nums){if(num == target){count++;}}return count;}
2. 二分法

有序数组 分别找到 taret 的左右边界 right - left +1
时间复杂度:O(logN) 空间复杂度:O(1)

public class Solution {public int search(int[] nums, int target) {int len = nums.length;if (len == 0) {return 0;}int firstPosition = findFirstPosition(nums, target);if (firstPosition == -1) {return 0;}int lastPosition = findLastPosition(nums, target);return lastPosition - firstPosition + 1;}private int findFirstPosition(int[] nums, int target) {int len = nums.length;int left = 0;int right = len - 1;while (left < right) {int mid = left + (right - left) / 2;// 注意这样写,可以从左边收缩待搜索区间的范围,进而找到第一次出现的位置if (nums[mid] < target) {// mid 以及 mid 左边都不是,下一轮搜索区间在 [mid + 1, right]left = mid + 1;} else {right = mid;}}if (nums[left] == target) {return left;}return -1;}private int findLastPosition(int[] nums, int target) {int len = nums.length;int left = 0;int right = len - 1;while (left < right) {int mid = left + (right - left + 1) / 2;// 注意这样写,可以从右边收缩待搜索区间的范围,进而找到最后一次出现的位置if (nums[mid] > target) {// mid 以及 mid 右边都不是,下一轮搜索区间在 [left, mid - 1]right = mid - 1;} else {left = mid;}}return left;}
}

【总结】

1.二分查找思路

2.排除法思考二分法


1、确定搜索区间初始化时候的左右边界,有时需要关注一下边界值。在初始化时,有时把搜索区间设置大一点没有关系,但是如果恰好把边界值排除在外,再怎么搜索都得不到结果。

2、无条件写上 while (left < right) ,表示退出循环的条件是 left == right,对于返回左右边界就不用思考了,因此此时它们的值相等;

3、先写下取整的中间数取法,然后从如何把 mid 排除掉的角度思考 if 和 else 语句应该怎样写。

(这里建议写两个注释。)

  • 一般而言,我都会把**“什么时候不是目标元素”**作为注释写在代码中,提醒自己要判断正确,这一步判断非常关键,直接影响到后面的代码逻辑。
  • 然后接着思考 mid 不是解的情况下,mid 的左右两边可能存在解,把下一轮搜索的区间范围作为注释写进代码里,进而在确定下一轮搜索区间边界的收缩行为时,不容易出错。

if 有把握写对的情况下,else 就是 if 的反面,可以不用思考,直接写出来。

** 说明:这种思考方式,就正正好把待搜索区间从逻辑上分成两个区间,一个区间不可能存在目标元素,进而在另一个区间里继续搜索,更符合“二分”的语义。**

4、根据 if else 里面写的情况,看看是否需要修改中间数下取整的行为。


上面已经说了,只有看到 left = mid 的时候,才需要调整成为上取整,记住这一点即可,我因为刚开始不理解这种写法,遇到很多次死循环,现在已经牢记在心了。

5、退出循环的时候,一定有 left == right 成立。有些时候可以直接返回 left (或者 right,由于它们相等,后面都省略括弧)或者与 left 相关的数值,有些时候还须要再做一次判断,判断 left 与 right 是否是我们需要查找的元素,这一步叫“后处理”。

// 有可能区间内不存在目标元素,因此还需做一次判断if (nums[left] == target) {return left;}return  -1;
public int searchInsert(int[] nums, int target) {int len = nums.length;if (len == 0) {return 0;}int left = 0;// 因为有可能数组的最后一个元素的位置的下一个是我们要找的,故右边界是 lenint right = len;while (left < right) {int mid = (left + right) >>> 1;// 小于 target 的元素一定不是解if (nums[mid] < target) {// 下一轮搜索的区间是 [mid + 1, right]left = mid + 1;} else {right = mid;}}return left;}



转载链接:https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/solution/er-fen-cha-zhao-fa-zhao-dao-di-yi-ci-chu-xian-de-w/

[剑指offer]面试题第[53-1]题[JAVA][在排序数组中查找数字-1][二分法][暴力法]相关推荐

  1. 【LeetCode】剑指 Offer 53 - I. 在排序数组中查找数字 I

    [LeetCode]剑指 Offer 53 - I. 在排序数组中查找数字 I 文章目录 [LeetCode]剑指 Offer 53 - I. 在排序数组中查找数字 I 一.二分法 总结 一.二分法 ...

  2. LeetCode-剑指 Offer 53 - I. 在排序数组中查找数字 I

    剑指 Offer 53 - I. 在排序数组中查找数字 I 思路一:二分单边 + 线性扫描 先用一次二分查找找到边界,再再边界里面寻找目标值 class Solution {public:int se ...

  3. 剑指offer面试题6 重建二叉树(java)

    注:(1)java中树的构建 (2)构建子树时可以直接利用Arrays.copyOfRange(preorder, from, to),这个方法是左开右闭的 1 package com.xsf.Sor ...

  4. 【菜鸡新手 - 剑指offer 03】[2021/1/17一刷] 找出数组中重复的数字 -三种解法|| 物归原主,测试碰撞法 || hash表测试碰撞法 || 排序+遍历法 ||python

    文章目录 题目解读 A. 书籍推荐解法:我起名为" 物归原主,测试碰撞"法 B. 基础尝试1:hash表 + 碰撞测试 (效果还行) C. 基础尝试2:排序+遍历 (效果差) C. ...

  5. 剑指Offer53-Ⅰ—在排序数组中查找数字

    剑指Offer53-Ⅰ 题意 统计一个数字在排序数组中出现的次数. 解法1-暴力循环 class Solution { public:int search(vector<int>& ...

  6. 剑指Offer - 面试题53 - I. 在排序数组中查找数字 I(二分查找的变形版本)

    1. 题目 统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2示例 2: 输入: nums = [5,7,7,8, ...

  7. 【剑指offer】面试题53 - 1:在排序数组中查找数字 I(java)

    统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 示例 2: 输入: nums = [5,7,7,8,8,10] ...

  8. 剑指offer面试题53 - I. 在排序数组中查找数字 I(二分查找)

    题目描述 统计一个数字在排序数组中出现的次数. 思路 详见链接 代码 class Solution:def search(self,nums:[int],target:int)->int:i, ...

  9. Leetcode 剑指 Offer 53 - I. 在排序数组中查找数字 I (每日一题 20210928)

    统计一个数字在排序数组中出现的次数.示例 1:输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 示例 2:输入: nums = [5,7,7,8,8,10], t ...

最新文章

  1. puppet最新源码包安装学习笔记
  2. IScroll5 上拉加载更多 及 item点击处理。
  3. ubuntu 16.04 连接 阿里云服务器
  4. php web开发应用教程,PHP-Web 应用程序开发:使用模板_PHP
  5. 如何在Java中处理ConcurrentModificationException? 在循环中从ArrayList中删除元素时要当心...
  6. JavaScript | 创建对象并通过JavaScript函数在表中显示其内容
  7. Ubuntu配置TFTP服务器
  8. [转] linux下shell中使用上下键翻出历史命名时出现^[[A^[[A^[[A^[[B^[[B的问题解决,Linux使用退格键时出现^H解决方法
  9. git bitbucket_如何在Bitbucket上创建新的Git存储库并查看提交的对象
  10. C语言考试上机操作题库(基础)(参考)
  11. java 递归层级拼接_使用递归方法拼接层级树
  12. 欧若科技通过 OpenKG 开放 Nebula Graph 图数据库
  13. 阿里云,AWS,HTTPS和企业支付宝配置
  14. 设计模式七大原则之合成/聚合复用原则(CARP)
  15. PHP操作redis详细讲解
  16. AD画螺旋形走线或者天线的操作
  17. 单片机实验笔记(汇编、Proteus仿真)(下)
  18. nor flash操作
  19. TC264 DMA相关部分代码
  20. 在10万以内的一个整数,它加上 100 后是一个完全平方数,再加上 168 又是一个完全平方数,请问该数是多少?

热门文章

  1. HttpWebRequest类
  2. 【转载】MOS开关(verilog)
  3. AS3 CookBook学习整理(八)
  4. app.config数据库路径问题
  5. windows10 C盘清理
  6. Eclipse中将java类打成jar包形式运行
  7. 10、jeecg 默认为空的字段值是如何被填充的?
  8. js 获取url参数(QueryString)
  9. c语言cgi函数库,cgic: 为C语言编写CGI的C函数库
  10. React Native 实现物流进度信息