《劍指offer》——整數中1出現的次數(從1到n整數中1出現的次數)

更多2019年的技術文章,歡迎關注我的微信公衆號:碼不停蹄的小鼠松(微信號:busy_squirrel),也可掃下方二維碼關注獲取最新文章哦~

T:

題目描述
求出113的整數中1出現的次數,並算出1001300的整數中1出現的次數?爲此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數。

兩種解決方式:找規律和暴力遍歷

  • 暴力遍歷

化爲字符串,或者用10取餘,都是一樣的道理:

code:

/**
 * 通過統計字符串的方式,計算其包含有多少個1
 * @param n
 * @return
 */
public int test(int n) {
	int count = 0;
	
	for (int i = 0; i <= n; i++) {
		String ss = String.valueOf(i);
		for (int j = 0; j < ss.length(); j++) {
			if (ss.charAt(j) == '1') {
				count ++;
			}
		}
	}		
	
	return count;
}
  • 找規律

這裏寫圖片描述

這個規律還真的不好找,我用了好幾張稿紙,纔算弄出來。。。

具體的細節或者規律的推導過程這裏不講了,就貼我在討論班上的留言吧:

這裏寫圖片描述

code:

 /**
 * T: 整數中1出現的次數(從1到n整數中1出現的次數)
 * 
 * 題目描述 求出1~13的整數中1出現的次數,並算出100~1300的整數中1出現的次數?
 * 爲此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,
 * 但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,
 * 可以很快的求出任意非負整數區間中1出現的次數。
 * 
 * date: 2015.11.19  19:22
 * @author SSS
 *
 */
public class Solution {
    
    /**
	 * 通過找規律求解
	 * 這個規律真心不好找。。。
	 * @param n
	 * @return
	 */
    public int NumberOf1Between1AndN_Solution(int n) {
    
        int count = 0;
        if (n == 0) {
			return count;
		}
	    // 該數的長度
	    int size = 0;
	    int tempN = n;
	    while ((int)(tempN / Math.pow(10, size)) != 0) {
			size ++;
		}
	    
	    // 標準值,即9,99,999,9999,……中含有多少個1
	    int []F = new int[size + 1]; // 下標爲0的地方空出來
	    F[0] = 0;	// 基本用不着 
	    F[1] = 1;
	    for (int i = 2; i < F.length; i++) {
			F[i] = (int) (10 * F[i - 1] + Math.pow(10, i - 1));
		}
	    
	    int []arr = new int[size + 1];
	    tempN = n;
	    int tempK = 0;
	    // 數字倒着放在數組中,便於計算
	    while (tempK < size) {
			arr[size - tempK] = (int) (tempN / Math.pow(10, size - tempK - 1));
			tempN = (int) (tempN % Math.pow(10, size - tempK - 1));
			tempK ++;
		}
	    
	    int []f = new int[size + 1];
	    // 先確定起點
	    if (arr[1] > 0) {
			f[1] = 1;
		} else {
			f[1] = 0;
		}
	    
	    for (int i = 2; i < f.length; i++) {
			f[i] = arr[i] * F[i - 1] + f[i - 1];
			int tail;
			int tailNum = (int) (n % Math.pow(10, i - 1));
			if (arr[i] == 0) {
				tail = 0;
			} else if (arr[i] == 1) {
				tail = tailNum + 1;
			} else {
				tail = (int) Math.pow(10, i - 1);
			}
			f[i] += tail;
		}
	    
	    count = f[size];
	    
	    return count;
    }
}

更多2019年的技術文章,歡迎關注我的微信公衆號:碼不停蹄的小鼠松(微信號:busy_squirrel),也可掃下方二維碼關注獲取最新文章哦~

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