您的位置:首页 > Web前端

剑指Offer--038-数字在排序数组中出现的次数

2016-05-06 23:00 465 查看

链接

牛客OJ:数字在排序数组中出现的次数

九度OJ:http://ac.jobdu.com/problem.php?pid=1349

GitHub代码: 038-数字在排序数组中出现的次数

CSDN题解:剑指Offer–038-数字在排序数组中出现的次数

牛客OJ九度OJCSDN题解GitHub代码
038-数字在排序数组中出现的次数1505-数字在排序数组中出现的次数剑指Offer–038-数字在排序数组中出现的次数038-数字在排序数组中出现的次数
您也可以选择回到目录-剑指Offer–题集目录索引

题意

题目描述

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

暴力方法

由于数组是有序的,因此我么通过一次遍历,对要查找的元素直接计数就可以了

#include <iostream>
#include <vector>

using namespace std;

//  调试开关
#define __tmain main

#ifdef __tmain

#define debug cout

#else

#define debug 0 && cout

#endif // __tmain

class Solution
{
public:
int GetNumberOfK(vector<int> data,int k)
{
if(data.size( ) == 0)
{
return 0;
}

int count = 0;
for(unsigned int i = 0;
i < data.size( ) && data[i] <= k;
i++)
{
if(data[i] == k)
{
count++;
}
}

return count;
}
};

int __tmain( )
{
Solution solu;

int arr[] = { 1, 2, 3, 3, 3, 3, 4, 5 };
vector<int> vec(arr, arr + 8);
cout <<solu.GetNumberOfK(vec, 3) <<endl;

return 0;
}


当然也可以使用STL中特定容易的计数功能

class Solution
{
public:
int GetNumberOfK(vector<int> data ,int k)
{
multiset<int> mData;
for(int i = 0; i < data.size( ); i++)
{
mData.insert(data[i]);
}

return mData.count(k);
}
};


分治–二分查找

二分查找(递归和非递归)

我们通过二分查找到指定的元素K后,然后再分别向前和向后查找总的个数

/* 先用二分查找找出某个k出现的位置,然后再分别向前和向后查找总的个数*/
class Solution
{
public:
int GetNumberOfK(vector<int> data,int key)
{
if(data.size( ) == 0)
{
return 0;
}

//  用二分查找查找到Key的位置
int index = BinarySearch(data, 0, data.size( ) - 1, key);
//int index = BinarySearch(data, key);
if(index == -1)
{
return 0;
}

int count = 1;
// 查找前面部分Key的个数
for(int j = index - 1;
j >= 0 && data[j] == key;
j--)
{
debug <<"pos = " <<j <<", data = " <<data[j] <<endl;
count++;
}

//  查找后面部分Key的个数
for(int j = index + 1;
j < data.size( ) && data[j] == key;
j++)
{
count++;
}

return count;
}

int BinarySearch(vector<int> &data, int begin, int end ,int key)
{
if(begin > end)
{
return -1;
}

int mid = (begin + end) / 2;
debug <<"mid = " <<mid <<", data = " <<data[mid] <<endl;
if(data[mid] == key)
{
return mid;
}
else if(data[mid] > key)
{
return BinarySearch(data, begin, mid - 1, key);
}
else if(data[mid] < key)
{
return BinarySearch(data,mid + 1, end, key);
}
return -1;
}

int BinarySearch(vector<int> array, int key)
{
int low = 0, high = array.size( ) - 1;

int mid;

while (low <= high)
{
mid = (low + high) / 2;

if(key == array[mid])
{
return mid;
}

if(key < array[mid])
{
high = mid - 1;
}

if(key > array[mid])
{
low = mid + 1;
}
}

return -1;
}
};


改进的二分查找,返回第一个和最后一个的位置

递归版

class Solution
{
/*二分查找 找到第一个K 和 最后一个K 二者位置相减*/
public:
int GetNumberOfK(vector<int> data ,int k)
{
if(data.empty())
{
return 0;
}

int number = 0;
int first = GetFirstIndex(data, k, 0, data.size( ) - 1);
int last  = GetLastIndex(data, k, 0, data.size( ) - 1);

if(first > -1 && last > -1)
{
number = last - first +1;
return number;
}
}

// 查找第一个的位置
int GetFirstIndex(vector<int> &data, int low, int high, int k)
{
if(low > high)
{
return -1;
}

int mid = (low + high) / 2;

if(data[mid] == k)
{
if((mid > 0 && data[mid-1] != k) || mid == 0)
{
return mid;
}
else
{
high = mid - 1;
}
}
else if(data[mid] > k)
{
high = mid - 1;
}
else if(data[mid] < k)
{
low = mid + 1;
}

return GetFirstIndex(data, k, low, high);
}

int GetLastIndex(vector<int> &data, int low, int high, int k)
{
if(low > high)
{
return -1;
}

int mid = (low + high) / 2;
if(data[mid]==k)
{
if((mid>0 && data[mid+1] !=k) || mid == high)
{
return mid;
}
else
{
low = mid +1;
}
}
else
{
if(mid>k)
{
high = mid-1;
}
else
{
low = mid+1;
}
}

return GetLastIndex(data,k,low,high);
}
};


非递归版

class Solution
{
public:
int GetNumberOfK(std::vector<char> array , int k)
{
if (array == null || array.size( ) == 0)
{
return 0;
}

int low = 0, high = array.size( ) - 1,
int first = 0, last = 0;

if (low == high)
{
if (array[0] != k)
{
return 0;
}
else
{
return 1;
}
}

int number = 0;
int first = GetFirstIndex(data, k, 0, data.size( ) - 1);
int last  = GetLastIndex(data, k, 0, data.size( ) - 1);

if(first > -1 && last > -1)
{
number = last - first +1;
return number;
}
else
{
return 0;
}
}

int GetFirstIndex(vector<int> &data, int low, int high, int k)
{
int mid
while (low < high)
{
int mid = (low + high) / 2;
if (array[mid] < k)
{
if (array[mid + 1] == k)
{
first = mid;
break;
}
low = mid + 1;
}
else
{
high = mid;
first = -1;
}
}

if (array[first + 1] != k)   // can't find it.
{
return 0;
}
}

int GetLastIndex(vector<int> &data, int low, int high, int k)
{
int last, mid;

while (low < high)
{
mid = (low + high) / 2;
if (array[mid] <= k)
{
last = mid;

if (array[mid + 1] > k)
{
break;
}
else if (mid + 1 >= high)
{
last++;
break;
}
low = mid + 1;
}
else
{
high = mid;
}
}
}
};


STL的

 ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)


算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置。

ForwardIter upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)


算法返回一个非递减序列[first, last)中第一个大于val的位置。

class Solution
{
public:
int GetNumberOfK(vector<int> data ,int k)
{
int upper = upper_bound(data.begin(),data.end(),k);
int low = lower_bound(data.begin(),data.end(),k);
return upper - low;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息