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

题目:

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

思路:

因为是排好序的数组,所以可以采用二分查找的算法。

一般最容易想到的思路是采用二分查找先找到一个,然后往他左右两边遍历,但是这个方法由于在n个数组中还可能有n个k,所以

查找的复杂度还是O(n)

可以先用二分查找算法找到第一个出现的位置,即当找到一个时,看它前面一个是否也是k或者是否已经是查找这段的第一个了

然后同样用二分查找找最后一个出现的位置。

 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4
 5 int count_number(vector<int>& vec,int n)
 6 {
 7     if(vec.empty())
 8         return 0;
 9     int len=vec.size();
10     int re=0;
11     int i=0;
12     int j=len-1;
13
14     int re1=0;
15     while(1)
16     {
17         if(i==j)
18         {
19             if(vec[i]==n)
20             {re1=i;break;}
21             else
22                 return 0;
23         }
24         int k=(j+i)/2;
25
26         if(vec[k]==n)
27         {
28             if(k==i)
29             {re1=k;break;}
30             if(vec[k-1]!=n)
31             {re1=k;break;}
32             j=k-1;
33         }
34         else if(vec[k]<n)
35         {
36             i=k+1;
37         }
38         else
39             j=k-1;
40     }
41
42     cout<<"re1="<<re1<<endl;
43
44     int re2=0;
45     i=0;
46     j=len-1;
47     while(1)
48     {
49         if(i==j)
50         {
51             if(vec[i]==n)
52             {re2=i;break;}
53             else
54                 return 0;
55         }
56         int k=(j+i)/2;
57
58         if(vec[k]==n)
59         {
60             if(k==j)
61             {re2=k;break;}
62             if(vec[k+1]!=n)
63             {re2=k;break;}
64             i=k+1;
65         }
66         else if(vec[k]<n)
67         {
68             i=k+1;
69         }
70         else
71             j=k-1;
72     }
73     cout<<"re2="<<re2<<endl;
74     re=re2-re1+1;
75     return re;
76 }
77
78 int main()
79 {
80     int ary[8]={1,2,3,3,3,3,4,5};
81     vector<int> vec(ary,ary+8);
82
83     cout<<count_number(vec,3)<<endl;
84     system("pause");
85 }
时间: 2024-10-26 20:08:51

剑指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]