題目:給定n個整數的數組A以及一個數x,設計一個分治算法,求出x在數組中出現的次數,並分析時間複雜度。
算法思想:
- 先將問題劃分爲大小近似相等的兩個字問題。
- 對子問題遞歸調用該算法進行處理,遞歸出口爲子問題只含一個元素,若該元素等於x,則返回x的出現次數爲1,若該元素不等於x,則返回0
- 原問題結果爲這兩個子問題所得結果之和。
核心代碼:
int Countx(int arr[],int p,int r,int x){
int q;
if(p==r){//p,r分別爲子序列的左右邊界下標,當兩者相遇時(即子問題只有一個元素)遞歸出口
if(arr[p]==x)//判斷是否等於x,是則返回1
return 1;
else
return 0;
}
else
q=(p+r)/2;//將問題不斷劃分爲兩子問題,直到子問題只有一個元素,遞歸結束
//q爲數組的中間位置
return(Countx(arr,p,q,x)+Countx(arr,q+1,r,x));//遞歸方程
}
完整代碼:
#include<stdio.h>
int Countx(int arr[],int p,int r,int x){
int q;
if(p==r){//p,r分別爲子序列的左右邊界下標,當兩者相遇時(即子問題只有一個元素)遞歸出口
if(arr[p]==x)//判斷是否等於x,是則返回1
return 1;
else
return 0;
}
else
q=(p+r)/2;//將問題不斷劃分爲兩子問題,直到子問題只有一個元素,遞歸結束
//q爲數組的中間位置
return(Countx(arr,p,q,x)+Countx(arr,q+1,r,x));//遞歸方程
}
int main(){
int arr[]={1,2,34,43,242,242,242,245};
int x,n;
printf("請輸入待查找的數據!\n");
scanf("%d",&x);
n=Countx(arr,0,7,x);
if(n==0)
printf("查無此數據!\n");
else
printf("查到了!該數據在數組中的個數爲%d\n",n);
return 0;
}
- 時間複雜度分析:
- 利用公式法得:T(n)= O(n)
- 爛尾:文章寫到這基本爛尾了,可能大家都有一個這樣的困惑,遞歸公式能否幫我們完成我們想要的結果,答案是肯定的。但是當我們帶數據進去推理,大部分情況是一團暈,搞得對學習算法越來越沒有信心,加油,那只是我們練的太少,多練肯定會懂得遞歸分治的套路,算法學習,切記眼高手低,還得多練,多去leedcode多刷題,加油!考慮到可能有些小夥伴,把遞歸和分治搞混淆!下面一個漫畫也許能解開你的心結。
- 遞歸與分治