码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode 233 Number of Digit One

时间:2015-08-04 10:38:45      阅读:96      评论:0      收藏:0      [点我收藏+]

标签:

 

这题属于需要找规律的题。先想一下最简单的情形:N = 10^n - 1

记X[i]表示从1到10^i - 1中 1 的个数,则有如下递推公式:X[i] = 10 * X[i - 1] + 10^(i - 1)

这个递推公式可以这么观察得到:

i = 0, X[0] = 0

i = 1, 从1到9, X[1] = 1 

i = 2, 从1到99, X[2] = 20:可以设想,把所有数都写成两位数(比如1写成01, 2写成02),我们暂且不统计最高位的1, 则首先至少有10 * X[1]个1,然后我们考虑最高位的1,它只存在于11,12...19,也是10个

i = 3,从1到999,X[3] = ? : 同样先不统计最高位的1,首先至少有10 * X[2]个1,再统计最高位,应该还要加上100(10^(3-1))

逐步思考,通项公式就出来了:X[i] = 10 * X[i - 1] + 10^(i - 1)

 

记我们要求解的函数为f(x)

现在我们考虑一般的N,假设它表示成10进制有n位:a[n]a[n-1]...a[1]

用C[i]表示f(a[i]a[i-1]...a[1])的结果

递推过程仍旧类似,但此时每一位的上限有了限制,不能自由的从0到9取值

a[i] = 0时,C[i] = C[i - 1]

a[i] = 1时:C[i] = X[i - 1] + C[i - 1] + a[i-1]a[i-1]...a[1] + 1

a[i] > 1时:C[i] = a[i] * X[i - 1] + 10 ^(i - 1) + C[i - 1]

	int base = 10;
	vector<int> digits;
	while (n >= 1) {
		digits.push_back(n % base);
		n /= base;
	}
	vector<int> nums;
	int s = 0;
	base = 1;
	for (int i = 0; i < digits.size(); i++) {
		s += base * digits[i];
		nums.push_back(s);
		base *= 10;
	}
	vector<int> C(digits.size() + 1, 0);
	vector<int> X(digits.size() + 1, 0);
	base = 1;
	for (int i = 1; i < C.size(); i++) {
		X[i] = 10 * X[i - 1] + base;
		if (digits[i - 1] == 0) {
			C[i] = C[i - 1];
		}
		else if (digits[i - 1] == 1) {
			C[i] = X[i - 1] + C[i - 1] + 1 + (i > 1 ? nums[i - 2] : 0);
		}
		else {
			C[i] = digits[i - 1] * X[i - 1] + C[i - 1] + base;
		}
		base *= 10;
	}
	return C[C.size() - 1];

    }

 

leetcode 233 Number of Digit One

标签:

原文地址:http://www.cnblogs.com/hustxujinkang/p/4701172.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!