【剑指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;
  }
}


相关文章
|
7月前
每日一题(づ ̄3 ̄)づ╭❤~(数字在升序数组中出现的次数,整数转换)
每日一题(づ ̄3 ̄)づ╭❤~(数字在升序数组中出现的次数,整数转换)
46 0
|
7月前
|
算法 Java
每日一题《剑指offer》数组篇之统计数字在排序数组中出现的次数
每日一题《剑指offer》数组篇之统计数字在排序数组中出现的次数
52 0
每日一题《剑指offer》数组篇之统计数字在排序数组中出现的次数
【剑指offer】-1~n整数中1出现的次数-31/67
【剑指offer】-1~n整数中1出现的次数-31/67
剑指offer JZ37数字在排序数组中出现的次数
剑指offer JZ37数字在排序数组中出现的次数
53 0
|
C++
剑指offer 55. 数字在排序数组中出现的次数
剑指offer 55. 数字在排序数组中出现的次数
86 0
剑指offer_数组---数字在排序数组中出现的次数
剑指offer_数组---数字在排序数组中出现的次数
45 0
剑指offer 44. 从1到n整数中1出现的次数
剑指offer 44. 从1到n整数中1出现的次数
74 0
|
算法 C语言
剑指Offer 第53题:数字在升序数组中出现的次数
剑指Offer 第53题:数字在升序数组中出现的次数
143 0
剑指Offer 第53题:数字在升序数组中出现的次数
|
算法 Java
在排序数组中查找数字I(剑指offer 53-I)
在排序数组中查找数字I(剑指offer 53-I)
|
算法 Java C#
数组中数字出现的个数(剑指offer 56-I)
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。