一道面試題:求一個正整數的因子個數


如:整數 15,有1, 15, 3,5 共4個因子。要求算法的復雜度為O(sqrt(N)).

 首先想到的方法是:逐個枚舉,從 1 到 N/2 + 1(當然也可以是 從 1 到 N),這樣算法的復雜到至少是O(N)的,

而且,其中還要去重,比如 24 = 4*6 = 6*4,這樣還要分配空間來存放找到的因子,並且每次添加的時候,還要

查找是否已經在列表中,采用二分查找也要logN,因此最終的算法復雜度也要達到O(NlogN)。不符合題目的要求。

其實,重復因子的出現是在sqrt(N)的附近,再加上題目給出的算法復雜度的提示,因此我們可以寫出如下的算法:

	/**
	 * 求正整數 N的因子數
	 * @param N
	 * @return
	 */
	public int factors(int N){
		if(1 == N) return 1;
		int count = 2;// 1 與 N 必是
		final int sqrt_N = (int)Math.sqrt(N);
		int r;
		for(int i = 2; i <= sqrt_N; i++){
			if(0 == N % i){
				if(i == sqrt_N){
					r = N / i;
					if(r == i){//比如 4 = 2 * 2;那么2 只能算一個
						count++;
					}else{
						count += 2;
					}
				}else{
					count += 2;
				}
			}
		}
		
		return count;
	}
	
	/**
	 * 有沒有漏掉呢?
	 * 
	 * 假設存在一個正整數 K,使得 K * M = N, 且  K 不在 1, sqrt(N)之間,且M 為正整數
	 * 那么 M必在(1, sqrt(N))之間,否則 K*M >sqrt(N)*sqrt(N) = N,與 K*M = N矛盾
	 * 即只要存在兩個正整數K, M,使得 K * M = N,那么K, M中必有一個在[1, sqrt(N)]區間中
	 */

 注釋部分,相當與算法正確性的證明。

當然,如果不調用系統的庫函數,可能還需要自己實現求一個整數的平方根的算法,根據本題要求,不要求精度太高,只需要

到 0.1就夠了。

 

擴展:如果N為負數呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM