1. 程式人生 > 其它 >劍指 offer程式碼解析——面試題32統計1到n中1出現的次數

劍指 offer程式碼解析——面試題32統計1到n中1出現的次數

本題的分析過程均在程式碼註釋中:

/**
 * 題目:輸入一個整數n,求從1到n這n個整數的十進位制表示中1出現的次數。
 * @author 大閒人柴毛毛
 * @date 2016年3月22日
 */
public class CountOne {
	/**
	 * 分析:本題常規思路如下:
	 * 從1開始遍歷這n個數,分別統計每個數中“1”出現的次數。
	 * 那麼,問題就轉化為“如何統計一個整數中1出現的次數?”
	 *
	 * 首先我們需要知道以下結論:
	 * 1.設整數為n,則n%10就能取到n的個位數;
	 * 2.n除以10後再取整其實就是把n的個位數砍掉。
	 * 基於上述結論,我們只要迴圈以下操作即可:
	 * 1.求整數n的餘數;
	 * 2.判斷餘數是否為1,若為1則將計數器加1;
	 * 3.重複上述過程,直到n變成為0為止。
	 * 程式碼如下:
	 */
	
	/**
	 * 統計1-n中“1”出現的次數
	 * @param n
	 * @return 返回1出現的次數(若返回-1表示程式出錯)
	 */
	public static int countOne(int n){
		//若n<1
		if(n<1){
			System.out.println("n<1!");
			return -1;
		}
		
		//建立計數器,用於統計1的個數
		int count = 0;
		
		//統計1-n中“1”出現的次數
		for(int i=1;i<=n;i++){
			//temp用於記錄當前整數
			int temp = i;
			while(temp>0){
				//判斷個位數是否為1
				if(temp%10==1)
					count++;
				//將temp的個位數砍掉
				temp /= 10;
			}
		}
		
		return count;
	}
	
	/**
	 * 上述方法需要對1-n分別進行掃描,而且對每個數還要進行m次掃描(m為數字的位數),因此效率並不高。
	 * 網上有一些大神提出了一些更高效的方法,但過於巧妙,只能就題論題,缺乏推廣的價值,因此這裡不再介紹。
	 * 若有更高效且具有推廣價值的方法,歡迎交流。
	 */
	
	
	/**
	 * 測試
	 */
	public static void main(String[] args){
		System.out.println(countOne(13));
	}
}