剑指Offer--038-数字在排序数组中出现的次数
2016-05-06 23:00
465 查看
链接
牛客OJ:数字在排序数组中出现的次数九度OJ:http://ac.jobdu.com/problem.php?pid=1349
GitHub代码: 038-数字在排序数组中出现的次数
CSDN题解:剑指Offer–038-数字在排序数组中出现的次数
牛客OJ | 九度OJ | CSDN题解 | GitHub代码 |
---|---|---|---|
038-数字在排序数组中出现的次数 | 1505-数字在排序数组中出现的次数 | 剑指Offer–038-数字在排序数组中出现的次数 | 038-数字在排序数组中出现的次数 |
题意
题目描述统计一个数字在排序数组中出现的次数。
暴力方法
由于数组是有序的,因此我么通过一次遍历,对要查找的元素直接计数就可以了#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; } };
相关文章推荐
- 查看github pages文档的方式
- 使用BAE的基于Web.py的简单博客程序
- 只有程序员看的懂的面试圣经|如何拿下编程面试
- 下一次技术面试时要问的 3 个重要问题
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- PHP程序员面试 切忌急功近利(更需要注重以后的发展)
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法