zoukankan      html  css  js  c++  java
  • (剑指Offer)面试题38:数字在排序数组中出现的次数

    题目:

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

    思路:

    1、顺序遍历

    顺序扫描一遍数组,统计该数字出现的次数。

    时间复杂度:O(n)

    2、二分查找

    假设我们需要找的数字是k,那么就需要找到数组中的第一个k和最后一个k出现的位置。

    如何通过二分查找得到第一个k的位置呢?

    取数组中间的数字与k作比较,

    如果该数字比k大,那么k只能出现在前半部分,那么下一轮只能在前半部分找;

    如果该数字比k小,那么k只能出现在后半部分,那么下一轮只能在后半部分找;

    如果该数字等于k,需要判断这是不是第一个k,如果该数字的前一个数字不是k,那么该数字就是第一个k,否则需要在前半部分继续寻找第一个k;

    寻找最后一个k的方法与寻找第一个k的方法一样。

    代码:

    #include <iostream>
    
    using namespace std;
    
    int getFirstK(int* data,int k,int start,int end){
        while(start<=end){
            int mid=start+((end-start)>>1);
            if(data[mid]==k){
                if((mid>0 && data[mid-1]!=k) || mid==0)
                    return mid;
                else
                    end=mid-1;
            }
            else if(data[mid]>k)
                end=mid-1;
            else
                start=mid+1;
        }
        return -1;
    }
    
    int getLastK(int* data,int length,int k,int start,int end){
        while(start<=end){
            int mid=start+((end-start)>>1);
            if(data[mid]==k){
                if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
                    return mid;
                else
                    start=mid+1;
            }
            else if(data[mid]<k)
                start=mid+1;
            else
                end=mid-1;
        }
        return -1;
    }
    
    int getNumberOfK(int* data,int length,int k){
        if(data==NULL || length<=0)
            return 0;
        int first=getFirstK(data,k,0,length-1);
        int last=getLastK(data,length,k,0,length-1);
        cout<<first<<" "<<last<<endl;
        if(first!=-1 && last!=-1)
            return last-first+1;
        return 0;
    }
    
    int main()
    {
        int A[]={1,2,3,3,3,3,4,5};
        int len=sizeof(A)/sizeof(A[0]);
        int k=3;
        cout << getNumberOfK(A,len,k) << endl;
        return 0;
    }
    

    在线测试OJ:

    http://www.nowcoder.com/books/coding-interviews/70610bf967994b22bb1c26f9ae901fa2?rp=2

    AC代码:

    class Solution {
    public:
        int GetNumberOfK(vector<int> data,int k) {
            int len=data.size();
            if(len<=0)
                return 0;
            int first=getFirstK(data,k,0,len-1);
            int last=getLastK(data,len,k,0,len-1);
    
            if(first!=-1 && last!=-1)
                return last-first+1;
            return 0;
        }
    
        int getFirstK(const vector<int> &data,int k,int start,int end){
            int mid;
            while(start<=end){
                mid=start+((end-start)>>1);
                if(data[mid]==k){
                    if((mid>0 && data[mid-1]!=k) || mid==0)
                        return mid;
                    else
                        end=mid-1;
                }
                else if(data[mid]>k)
                    end=mid-1;
                else
                    start=mid+1;
            }
            return -1;
        }
    
        int getLastK(const vector<int> &data,int length,int k,int start,int end){
            int mid;
            while(start<=end){
                mid=start+((end-start)>>1);
                if(data[mid]==k){
                    if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
                        return mid;
                    else
                        start=mid+1;
                }
                else if(data[mid]>k)
                    end=mid-1;
                else
                    start=mid+1;
            }
            return -1;
        }
    };
  • 相关阅读:
    为什么Java中字符串是不可变的
    面试问题-使用Java线程做数学运算
    Java中静态类型检查是如何进行的
    Java是如何处理别名(aliasing)的
    Java字符串中常见的10个问题
    深入理解“HelloWorld”小程序
    往文件中按行写入数据
    HashSet vs TreeSet vs LinkedHashSet
    FileOutputStream VS FileWriter
    CentOS下添加Root权限用户(超级用户)方法
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4678344.html
Copyright © 2011-2022 走看看