算法題02:遞歸:大整數乘法的變式、二分搜索

一、給定 22 個大整數 uuvv,它們分別有 mm 位和 nn 位數字,且 mnm\le n。 當 mmnn 小很多時,設計一個算法用 O(nmlog(3/2))O(nm^{\log(3/2)})時間求出 uvuv 的值。說明分析思路,寫出僞代碼,並寫出算法複雜度分析過程。

​ 考慮到mmnn小很多,可以把m位乘n位的問題拆解爲多個m位相乘的問題,然後利用已經得出的m位相乘的優化算法進行計算。

​ 將vv 分解爲n/mn/m 段,使得每段爲mm位,那麼類似大整數乘法的計算方法,這裏計算uvuv就相當於計算n/mn/mmm位的乘法運算,然後在進行n/m1n/m-1次加法。利用已經知道的分治法求mm位乘積複雜度爲O(mlog3)O(m^{log^{3}}),所以求uvuv的時間複雜度爲O((n/m)mlog3)+O(n/m)=O(nmlog(3/2))O((n/m)m^{log^{3}}) + O(n/m) = O(nm^{log(3/2)}).

僞代碼

/**
 *計算位數爲m,n,且m<n的兩十進制數乘積,使得時間複雜度爲O(nm^log(3/2))
 */

//十進制的同位大整數乘法,且位數爲n.
public static int bigMul(int x,int y,int n){
    if(n == 1){
        return x*y;	
    }
    int k = n/2;
    int b = x % pow(10,n/2);
    int a = x / pow(10,n/2);
    int d = y % pow(10,n/2);
    int c = y / pow(10,n/2);
    return bigMul(a,c,k)*pow(2,2*k)+((a-b)*(d-c)+bigMul(a,c,k)+bigMul(b,d,k))*pow(2,k)+bigMul(b,d,k);
}
public static int main(){
    Scenner(int u,int v,int m,int n);	//輸入u,v,m,n
    int res=0;							//結果
    int divide_V[n/m]; 		//定義存放將v分爲n/m個長爲m的數的數組
    //將v劃分並存入數組
    for i=0 to i=n/m-1:
    	divide_V[i] = v%pow(10,m);
    	v /= pow(10,m);
    //將數組內的數與m使用上面定義的函數分別相乘,再分別乘以對相應段的位數,如2343->23 43,23參與乘法後還要乘10的2次方,最後全部相加
    for i=0 to i=n/m-1:
    	res += bigMul(u,divide_V[i],m) * i*pow(10,m);//第i段的應該補的位數恰爲i*10的m次方
    
    return res;
}

二、 設 nn不同的整數(可能爲正整數、負整數或者0)排序後存於數組 T[0:n1]T[0:n-1]中。 設計一個算法,判斷數組中是否存在不動點(若元素 T[i]T[i] 等於 ii, 即 T[i]=iT[i]=i,則此元素爲不動點)。說明分析思路,寫出僞代碼,並寫出算法複雜度分析過程。

解:

​ 因爲每個數都是整數,並且數組是升序的,假設其中某個位置的A[i] = i,那麼可以肯定的值,之前的A[x] > x,之後的A[x] < x,那麼這個問題除了判斷相等的條件不同,其他和課上講的二分搜索幾乎一樣,所以可以和二分搜索一樣使用分治法和遞歸進行計算。

​ 因爲每次都是執行二分操作,每次遞歸中間的操作複雜度都爲O(1)O(1),所以,總的複雜度的遞歸表達式爲

T(n) = T(n/2) + O(1)

​ 由主方法得時間複雜度爲:O(logn)O(logn)

僞代碼:

public static int hasPoint(int start, int end,int T[]){
    int mid = (end - start) / 2 + start;
    if(start > end):
        return false;
    
    if(T[mid] == mid):		
    	return true;
    else if(T[mid]<mid):
    	start = mid+1;			//此時值小於下標,應該在右邊
    	return hasPoint(start,end,T);
    else if(T(mid)>mid)						//此時值大於下標,那麼可能的值就在左邊
    	end = mid-1;
        return hasPoint(start,end T);
    return false;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章