第三章:查詢與排序(下)----------- 3.10 實戰解題_哪個數字超過了一半?
哪個數字超過了一半?
陣列中有一個數字出現的次數,超出了陣列長度的一般,找出這個數字。
解法1:排序後返回arr[N/2], Nlg(N)。
解法2:hash統計。
解法3:分割槽,進行順序統計 ; 需要改動原來陣列的內容 。
解法4: 不同的數,進行消除, O(N)。
#include <iostream>
#include<algorithm>
using namespace std;
int selectK(int A[],int p,int r,int k);
int partition(int A[],int p,int r);
//解法1:排序後返回arr[N/2], Nlg(N)
void solve1(int arr[],int length){
sort(arr,arr+length);
cout<<arr[length/2];
}
//解法2:hash統計
//解法3:分割槽,進行順序統計 ; 需要改動原來陣列的內容
void solve3(int arr[],int length){
int res=selectK(arr,0,length-1,length/2);
cout<<res;
}
//解法4: 不同的數,進行消除, O(N)
void solve4(int arr[],int length){
//候選數
int candidate=arr[0];
int nTime=1;
for(int i=1;i<length;i++){
//兩兩消減為0,應該把現在的元素作為候選值
if(nTime==0){
candidate=arr[i];
nTime=1;
continue;
}
//遇到和候選值相同的,次數+1
if(arr[i]==candidate){
nTime++;
}
else{
nTime--;
}
}
cout<<candidate;
}
int main()
{
int arr[]={0,1,2,1,1};
int len=5;
solve1(arr,len);
cout<<endl;
solve3(arr,len);
cout<<endl;
solve4(arr,len);
return 0;
}
int selectK(int A[],int p,int r,int k){
int q=partition(A,p,r); //主元下標
int qK=q-p+1; //主元是第幾個元素(排好序後)
if(qK==k){
return A[q];
}
else if(qK>k){
return selectK(A,p,q-1,k);
}
else{
return selectK(A,q+1,r,k-qK);
}
}
//三點中值法
int partition(int A[],int p,int r){
//優化: 在p、r、mid之間,選一箇中間值作為主元
int midIndex=p+((r-p)>>1); //中間下標
int midValueIndex=-1; //中值的下標
if(A[p]<=A[midIndex]&&A[p]>=A[r]){
midValueIndex=p;
}
else if(A[r]<=A[midIndex]&&A[r]>=A[p]){
midValueIndex=r;
}
else{
midValueIndex=midIndex;
}
swap(A[p],A[midValueIndex]);
int pivot=A[p];
int left=p+1;//掃描指標
int right=r; //右側指標
while(left<=right){
//left不停往右走,直到遇到大於主元的元素
while(A[left]<=pivot) left++; //迴圈退出時,left一定是指向第一個大於主元的位置
while(A[right]>pivot) right--; //迴圈退出時,right一定是指向最後一個小於等於主元的位置
if(left<right){
swap(A[right],A[left]);
}
}
//while退出時,兩者交錯,且right指向的是最後一個小於等於主元的位置,也就是主元應該待的位置
swap(A[p],A[right]);
return right; //返回主元在交換完成後的下標
}
相關文章
- 第三章:查詢與排序(下)----------- 3.21基數排序排序
- 第三章:查詢與排序(下)----------- 3.19 計數排序排序
- 第三章:查詢與排序(下)----------- 3.14 逆序對個數排序
- 第三章:查詢與排序(下)----------- 3.27 用計數排序解決員工年齡問題排序
- 第三章:查詢與排序(下)----------- 3.20桶排序排序
- 第三章:查詢與排序(下)----------- 3.29 題解:判斷陣列的包含問題排序陣列
- 第三章:查詢與排序(下)----------- 3.23 相關題解:排序陣列中找和的因子排序陣列
- 第三章:查詢與排序(下)------------- 3.8題解_調整陣列順序-奇數在左偶數在右排序陣列
- 第三章:查詢與排序(下)----------- 3.28 特殊排序(利用sort函式)排序函式
- [劍指offer題解][Java]陣列中出現次數超過一半的數字Java陣列
- 第三章:查詢與排序(下)----------- 3.16堆的概念及堆排序思路排序
- 第二章 :查詢與排序-------2.17解題實戰_旋轉陣列的最小數字(改造二分法)排序陣列
- 第三章:查詢與排序(下)----------- 3.12 實踐_最小可用id是多少排序
- 陣列中出現次數超過一半的數字陣列
- 48 陣列中出現次數超過一半的數字陣列
- 第三章:查詢與排序(下)----------- 3.9 最快效率求出亂序陣列中第k小的數排序陣列
- 第三章:查詢與排序(下)----------- 3.15基礎學習_樹、二叉樹、堆排序排序二叉樹
- 第二章 :查詢與排序-------2.16 解題實戰_小白上樓梯(遞迴設計)排序遞迴
- 查詢與排序02,折半查詢排序
- 第三章 :查詢與排序-------3.6快排在工程實踐中的優化排序優化
- 第三章:查詢與排序(下)----------- 3.22 總結:10種排序演算法的對比分析排序演算法
- 第三章 :查詢與排序-------3.2你需要掌握的快速排序演算法排序演算法
- 劍指offer之列印超過陣列一半的數字陣列
- 第三章:查詢與排序(下)----------- 3.11 趣味擴充_尋找發帖水王排序
- JZ-028-陣列中出現次數超過一半的數字陣列
- 每日一練(20):陣列中出現次數超過一半的數字陣列
- Oracle分頁查詢中排序與效率問題解決方法詳解Oracle排序
- 查詢與排序05,氣泡排序排序
- 查詢與排序04,插入排序排序
- 查詢與排序03,選擇排序排序
- 第三章 :查詢與排序(下)-------3.1分治法介紹及關鍵點解析排序
- 第二章 :查詢與排序---------遞迴、查詢與排序補充排序遞迴
- 第三章 :查詢與排序-------3.7分治模式的完美詮釋_歸併排序排序模式
- 每日一練(24):在排序陣列中查詢數字排序陣列
- 第三章:查詢與排序(下)----------- 3.25 知其然知其所以然:小頂堆與topK的具體程式碼實現排序TopK
- 查詢陣列中出現次數大於陣列長度一半的數字陣列
- Elasticsearch 按照標籤匹配個數優先排序查詢Elasticsearch排序
- 每日一題 - 劍指 Offer 53 - I. 在排序陣列中查詢數字 I每日一題排序陣列