剑指Offer53-Ⅰ

题意

统计一个数字在排序数组中出现的次数。

解法1—暴力循环

class Solution
{
public:int search(vector<int>& nums, int target) {int count=0;for(auto& num:nums){if(num==target)count++;}return count;}
};

解法2—哈希表

class Solution
{
public:int search(vector<int>& nums, int target) {unordered_map<int,int> umap;for(auto& num:nums){umap[num]++;}return umap[target];}
};

解法3—二分法

由题目可知,nums是一个非递减数组。排序数组中的搜索问题,首先想到 二分法 解决。

排序数组 nums 中的 所有target数字 形成一个窗口,记窗口的 左 / 右边界 索引分别为 left 和 right ,分别对应窗口左边 / 右边的首个元素。

本题要求统计数字 target 的出现次数,可转化为:使用二分法分别找到 左边界 left 和 右边界 right ,易得数字 target 的数量为 right - left - 1。


这样的话呢,我们会把算法流程分为两部分,第一部分是查找左边界,第二部分是查找右边界,有没有办法将二者统一起来呢?

假设定义我们的二分查找函数是 f,当它的输入参数是x的时候,我们令 f(x)返回结果为x在有序数组nums中插入的位置,如果 f(x) 返回的结果是i的话,这就说明在nums的[0,i-1]闭区间的范围内的所有元素统统是 小于等于x 的;而在nums的[i+1,n-1]闭区间内所有的数字统统是大于x的。

例如:

f(7) = 3。即target形成的窗口的第一个位置。

f(8) = 5。即target形成的窗口的最后一个位置的下一个位置。

这样,直接返回 f(8)-f(7)就可以得到最终的答案了。

f函数算法解析:

  1. 初始化: 左边界 L = 0,右边界 R = len(nums) - 1。
  2. 循环二分:当L大于R时跳出循环
    1. 计算中点 m = L+(R-L)/2 (向下取整);
    2. 若 nums[m] ≤  target ,中点值比target小或者等于它,target插入位置肯定在[m+1,R] 闭区间了,因此执行 L = m + 1;

    3. 若 nums[m] > target,中点值比target大,target插入位置肯定在中点之前了,即[L,m-1]闭区间 ,因此执行 R = m - 1;

  3. 返回值: 返回最终的答案L。

C++实现

class Solution
{
public:int f(vector<int>& nums,int x){//寻找x的右边界//本质上来说就是查找数字x在Nums中的插入位置//若数组中存在值相同的元素,则插入位置为这些元素的右边int L=0,R=nums.size()-1;//当左右边界(L和R)指向同一个位置的时候,并没有办法判断 m 位置处的元素是≤x还是>x//因为我们最终返回的是L,而如果说 nums[m]≤x,L是需要在原有基础上加一的//否则,若nums[m]>x,L不会被改变,应该改变R,使得R<L,跳出循环。//所以即使 L等于R的时候,依然要判断 m处位置的元素与x的大小关系。while (L<=R){int m = L+(R-L)/2;if(nums[m]<=x)L=m+1;elseR=m-1;}return L;}int search(vector<int>& nums, int target) {//去找 (target-1) 的右边界,实际上就是查找target的左边界所在位置//主要是找位置,而不是找数字存不存在,target-1的目标是找到离target的左窗口最近的那个位置点。return f(nums,target)-f(nums,target-1);}
};

剑指Offer53-Ⅰ—在排序数组中查找数字相关推荐

  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 - 面试题53 - I. 在排序数组中查找数字 I(二分查找的变形版本)

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

  4. 剑指 Offer 53 - I. 在排序数组中查找数字 I(二分法)

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

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

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

  6. 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 ...

  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

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

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

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

最新文章

  1. Hobbit玩转Zynq MPSoC系列之2:TPG输入+VCU编码+rtp网络传输
  2. js微信小程序页面左上角返回跳转指定页面
  3. 我是一个请求,我该何去何从
  4. 使用Django的models创建mysql数据库
  5. navicat链接mysql
  6. Autobook中文版(七)—9.一个小的GNU Autotools项目
  7. imagemagick, imagick和magickwand的安装
  8. HoloLens 2开发:获取并渲染双手
  9. Android 开发之 ---- 底层驱动开发(一)
  10. linux 6.5 mongdb php扩展插件,linux下为php添加mongodb扩展
  11. paip.html调试工具--显示控件名称与值
  12. Bootstrap视频教程百度云盘免费下载地址-CSDN免费下载
  13. oracle 11g 创建表空间
  14. 【JAVA】Retrofit详解和使用
  15. B+树数据库加锁历史
  16. 股市投资必修课二十三--增长的导向
  17. 几款科学计算显卡对比(GTX Titan X、GTX 980、Tesla K40 K80 及quadro K4200) 科学计算显卡的两个主要性能指标: 1、CUDA compute capabili
  18. 普通计算机电缆,计算机电缆和普通电缆有什么区别吗?
  19. 数据运营与数据分析闲谈
  20. html崩溃手机代码15,这12行代码分分钟让你电脑崩溃手机重启

热门文章

  1. 广告点击流量实时统计
  2. 【IOS】Firebase(Google、Facebook、Apple、Guest)登录,FCM,Apple In-App,Kakao
  3. 网页登录华为云空间,查看空间内容
  4. Opencv图像分割与Watershed算法
  5. spring cloud灰度发布快速上下线问题解决
  6. 3个小技巧,让你的阅读效率翻倍
  7. Python——email模块
  8. 服务器统一计算系统,思科统一计算系统(UCS)
  9. matlab 吸引域,科学网—非线性方程组的吸引域和分界线 - 王龙飞的博文
  10. matplotlib bar3d画3d柱状图