【剑指offer】面试题38:数字在排序数组中出现的次数

题目:

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

思路:

对二分查找进行改进,找到数字在数组中第一次出现和最后一次出现的位置,这样就得到它出现的次数。

以找第一次出现的位置为例:如果mid元素大于k,则在前半段找;如果小于k,则在后半段找;如果等于k,则要看mid的前一个元素是不是k,如果是,则在前半段找,如果不是,则这就是第一次出现的位置。

时间复杂度O(logn)。

代码:

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        if(data.size()<=0)  return 0;//OMG!这里也是应该输出0

        int first=GetFirstK(data,k,0,data.size()-1);
        int last=GetLastK(data,k,0,data.size()-1);
        if(first>=0 && last>=0)
        {
            return last-first+1;
        }

        return 0;//OMG!这里应该是0啊
    }
private:
    int GetFirstK(const vector<int> &data, int k, int begin, int end)
    {
        if(begin<0 || end>=data.size() || begin>end)  return -1;

        int res=-1;
        int mid=begin+(end-begin)/2;
        if(data[mid]>k)
            res=GetFirstK(data,k,begin,mid-1);
        else if(data[mid]<k)
            res=GetFirstK(data,k,mid+1,end);
        else
        {
            if(mid==0 || (mid>0 && data[mid-1]!=k))
                res=mid;
            else
                res=GetFirstK(data,k,begin,mid-1);
        }

        return res;
    }

    int GetLastK(const vector<int> &data, int k, int begin, int end)
    {
        if(begin<0 || end>=data.size() || begin>end)  return -1;

        int res=-1;
        int mid=begin+(end-begin)/2;
        if(data[mid]>k)
            res=GetLastK(data,k,begin,mid-1);
        else if(data[mid]<k)
            res=GetLastK(data,k,mid+1,end);
        else
        {
            if(mid==data.size()-1 || (mid<data.size()-1 && data[mid+1]!=k))
                res=mid;
            else
                res=GetLastK(data,k,mid+1,end);
        }
        return res;//!!!忘了这一句,找了好长时间错误!!!
    }
};
时间: 2024-12-28 14:44:35

【剑指offer】面试题38:数字在排序数组中出现的次数的相关文章

剑指offer 面试题38—数字在排序数组中出现的次数

题目: 统计一个数字在排序数组中出现的次数.例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4. 解法一:O(n) 顺序遍历 解法二:O(logn) 用二分查找,分别找出第一个3,和最后一个3的位置,然后计算个数. #include <stdio.h> int GetFirstK(int* data,int length,int k,int start,int end) { if(start > end) return -1; int m

【剑指offer】题目38 数字在排序数组中出现的次数

思路: 应该是用二分查找分别找到该数字第一次和最后一次出现的位置,相减即可.O(logn) int findLeft(int a[], int n, int num) { int l = 0, r = n - 1; while(l <= r) { int m = l + (r - l) / 2; if(a[m] == num) //与普通二分查找的区别在等于这里 { if(m == 0 || a[m - 1] != num) //如果这是第一个数字或者它前面的数字不是num那么这个位置就是第一个

剑指offer(二十七)之数字在排序数组中出现的次数

题目描述 统计一个数字在排序数组中出现的次数 我用了两种方法求解,思路都比较简单直接,看代码都懂了,就不做介绍啦 代码1: <span style="font-size:18px;">public class Solution { public int GetNumberOfK(int [] array , int k) { int num=0; for(int i=0;i<array.length;i++){ if(array[i]==k){ num++; } }

《剑指offer》:[38]数字在排序数组中出现的次数

"沟通.学习能力就是看面试者能否清晰.有条理地表达自己,是否会在自己所得到的信息不够的情况下主动发问澄清,能否在得到一些暗示之后迅速做出反应纠正错误"                                                                                                                   ---陈黎明(MSoft-SDE) 题目:统计一个数字在排序数组中出现的次数.例如输入排序数组{1,2,3,3

面试题38_数字在排序数组中出现的次数

题目描写叙述 统计一个数字在排序数组中出现的次数. 解题思路 数组是排序的,所以反复出现的数字是相邻排列的. 用二分查找算法,找到第一次出现的位置.和 最后一次出现的位置. 推断第一次出现的位置条件为:当前数字的前一个是否与之相等.若是则继续查找,否则该位置就是第一次出现的位置. 推断最后一次出现的位置条件为:当前数字的后一个是否与之相等,若是则继续查找,否则该位置就是最后一次出现的位置. 出现的次数= last - first +1 时间复杂度:O(logn) 实现代码 class Solut

面试题:数字在排序数组中出现的次数

题目描述:统计一个数字在排序数组中出现的次数. 代码: public class Solution { public int GetNumberOfK(int [] array , int k) { if(array.length==0||array==null) return 0; int count=0; for(int i=0;i<array.length;i++){ if(array[i]==k) count++; } return count; } } 原文地址:https://www

剑指Offer面试题:2.二维数组中的查找

一.题目:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 例如下面的二维数组就是每行.每列都递增排序.如果在这个数组中查找数字7,则返回true:如果查找数字5,由于数组不含有该数字,则返回false. 二.解题思路 首先选取数组中右上角的数字.如果该数字等于要查找的数字,查找过程结束:如果该数字大于要查找的数字,剔除这个数字所在的列:如果该数字小于要查

剑指offer 38 数字在排序数组中出现的次数

自己的写法 class Solution { public: int GetNumberOfK(vector<int> data ,int k) { int length = data.size(); if(length <= 0) return 0; for(int i = 0;i < length;i++){ } int index1 = GetFirst(data,k,0,length-1); int index2 = GetLast(data,k,0,length-1);

38.数字在排序数组中出现的次数

半段查找. int GetFirstK(int* data, int length, int k, int start, int end) { if (start > end) return -1; int middleIndex = (start + end) / 2; int middleData = data[middleIndex]; if (middleData == k) { if ((middleIndex > 0 && data[middleIndex - 1]

剑指offer——面试题38:数字在排序数组中出现的次数(利用二分查找来找第一次和最后一次的位置)

题目: 统计一个数字在排序数组中出现的次数. 思路: 因为是排好序的数组,所以可以采用二分查找的算法. 一般最容易想到的思路是采用二分查找先找到一个,然后往他左右两边遍历,但是这个方法由于在n个数组中还可能有n个k,所以 查找的复杂度还是O(n) 可以先用二分查找算法找到第一个出现的位置,即当找到一个时,看它前面一个是否也是k或者是否已经是查找这段的第一个了 然后同样用二分查找找最后一个出现的位置. 1 #include<iostream> 2 #include<vector> 3