【剑指offer】-数字在排序数组中出现的次数-32/67

简介: 【剑指offer】-数字在排序数组中出现的次数-32/67

1. 题目描述

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

2. 题目分析

  1. 题主一开始的方法:看见有序,使用二分,查找到target,向前向后分别遍历到不等于target的数字,因为数组中的target出现的次数是不确定的,所以,可能查找到n次,相当于O(n);
  2. 面试中,这种写法会被paas掉,所以我们需要用二分查找找到第一次出现target的下标,最后一次出现target的下标,
  3. 对于target出现的第一次下标,采用以下方式
    当mid == 0的时候,也就是证明当前的数是从下标0开始的,则直接返回0(mid)
    为了防止数组的越界,我们需要使当前的mid>0且array[mid-1]!=key
    对于:right = mid - 1;我们可以理解成当前的key是位于中间的那一个,所以我们需要减少范围,也就是缩小right的值,让mid向前遍历。
if (array[mid] == key) {
        if ((mid == 0) || (mid > 0 && array[mid - 1] != key)) {
          return mid;
        } else {
          right = mid - 1;
        }
    }
  1. 对于target出现的最后一次下标,采取以下方式
    当mid == array.lenth - 1的时候,也就是证明当前的数一直到最后。则直接返回mid
    为了防止数组的越界,我们需要使当前的mid对于:i = mid + 1;我们可以理解成当前的key是位于中间的那一个,所以我们需要减少范围,也就是扩大left的值,让mid向后遍历。
if (array[mid] == key) {
        if (mid == array.length - 1 || mid < array.length - 1 && array[mid + 1] != key)   {
          return mid;
        } else {
          left = mid + 1;
        }
        }
  1. 最后,我们返回(第二次出现的下标 - 第一次出现的下标 + 1)

3. 题目代码

class Solution {
    public int search(int[] nums, int target) {
    int num1 = erfenFirst(nums, 0, nums.length - 1, target);
    int num2 = erfenSecond(nums, 0, nums.length - 1, target);
    return num2 - num1 + 1;
  }
  public static int erfenFirst(int[] array, int left, int right, int key) {
    int mid = 0;
    while (left <= right) {
      mid = (left + right) / 2;
      if (array[mid] == key) {
        if ((mid == 0) || (mid > 0 && array[mid - 1] != key)) {
          return mid;
        } else {
          right = mid - 1;
        }
      } else if (array[mid] > key) {
        right = mid - 1;
      } else {
        left = mid + 1;
      }
    }
    return 1;
  }
  public static int erfenSecond(int[] array, int left, int right, int key) {
    int i = left;
    int j = right;
    while (i <= j) {
      int mid = (i + j) / 2;
      if (array[mid] == key) {
        if (mid == array.length - 1 || mid < array.length - 1 && array[mid + 1] != key) {
          System.out.println(mid);
          return mid;
        } else {
          i = mid + 1;
        }
      } else if (array[mid] > key) {
        j = mid - 1;
      } else {
        i = mid + 1;
      }
    }
    return 0;
  }
}


相关文章
|
人工智能 Java
零基础五步骤,从零开始天猫精灵
零基础五步骤,从零开始天猫精灵
1330 1
零基础五步骤,从零开始天猫精灵
Xcode12在storyboard添加组件和事件,添加新页面及跳转
Xcode12界面有所改变,导致一些按钮位置变动。比如为storyboard添加组件的按钮移至如下位置:
2269 0
使用qemu来dump虚拟机的内存,然后用crash来分析
使用qemu来dump虚拟机的内存,然后用crash来分析
|
10月前
|
机器学习/深度学习 人工智能 JavaScript
JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景
本文探讨了JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景。JavaScript将注重性能优化、跨平台开发、AI融合及WebAssembly整合;TypeScript则强调与框架整合、强类型检查、前端工程化及WebAssembly的深度结合。两者结合发展,特别是在Vue 3.0中完全采用TypeScript编写,预示着未来的Web开发将更加高效、可靠。
379 4
|
供应链 监控 Java
【开题报告】基于SpringBoot的药店药品管理系统的设计与实现
【开题报告】基于SpringBoot的药店药品管理系统的设计与实现
1115 0
|
存储 算法 关系型数据库
探索MySQL递归查询,优雅的给树结构分页!
总结起来,对于MySQL中的树结构数据,递归查询结合预排序遍历树算法可以实现优雅的分页,但需要注意性能优化和数据更新的问题。这项技术提供了一种高效处理层级数据的工具,使得开发者可以在复杂的数据结构下实现直观和可靠的数据查询。
705 1
|
Linux 编译器 C语言
Linux中的pkg-config:简化库依赖管理的利器
**pkg-config**是Linux下管理库依赖的工具,它通过读取库的`.pc`文件提供编译和链接参数。使用`pkg-config --cflags --libs &lt;library&gt;`获取编译和链接选项,例如`gcc -o test test.c $(pkg-config --cflags --libs glib-2.0)`。能进行版本检查、参数提取、依赖管理和路径搜索。列出所有包用`pkg-config --list-all`。最佳实践包括确保库正确安装、检查版本、配置`PKG_CONFIG_PATH`及使用构建工具。
|
存储 canal Java
两个例子带你入门 Disruptor
Disruptor 是英国外汇交易公司 LMAX 开发的一个高性能队列。很多知名开源项目里,比如 canal 、log4j2、 storm 都是用了 Disruptor 以提升系统性能 。 这篇文章,我们通过两个例子一步一个脚印帮助同学们入门 Disruptor 。
两个例子带你入门 Disruptor
|
机器学习/深度学习 自然语言处理 运维
算法干货|主动学习算法学习笔记
算法干货|主动学习算法学习笔记
958 0
算法干货|主动学习算法学习笔记
|
监控 关系型数据库 MySQL
CentOS7下部署开源监控平台Cacti(下)
CentOS7下部署开源监控平台Cacti(下)
762 0
CentOS7下部署开源监控平台Cacti(下)

热门文章

最新文章