計數問題(分治算法實現)

題目:給定n個整數的數組A以及一個數x,設計一個分治算法,求出x在數組中出現的次數,並分析時間複雜度。

算法思想:

  1. 先將問題劃分爲大小近似相等的兩個字問題。
  2. 對子問題遞歸調用該算法進行處理,遞歸出口爲子問題只含一個元素,若該元素等於x,則返回x的出現次數爲1,若該元素不等於x,則返回0
  3. 原問題結果爲這兩個子問題所得結果之和。

核心代碼:

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多刷題,加油!考慮到可能有些小夥伴,把遞歸和分治搞混淆!下面一個漫畫也許能解開你的心結。
  • 遞歸與分治

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章