微软面试算法题

legend115599 2009-09-12 12:23:13
给定一个十进制正整数N,写下从1开始,到N的所有正数,然后数出其中出现所有1的个数。
那种循环套嵌浪费一摩尔多时间的常规算法就不要来了哈,人家要的是效率
...全文
708 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
bvbook 2009-10-21
  • 打赏
  • 举报
回复
《编程之美——微软技术面试心得》
super_chris 2009-09-17
  • 打赏
  • 举报
回复
编程之美啊
warm_gan 2009-09-17
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 gumbour 的回复:]
这种题目给一只笔很多人会用正确的算法。

给一台电脑可能很多人的算法就不咋样了
[/Quote]
同意
ljooo 2009-09-16
  • 打赏
  • 举报
回复
我觉得可以做为小学竞赛题。
bingshanzhiling 2009-09-15
  • 打赏
  • 举报
回复
接分,学习
gumbour 2009-09-15
  • 打赏
  • 举报
回复
这种题目给一只笔很多人会用正确的算法。

给一台电脑可能很多人的算法就不咋样了
gumbour 2009-09-15
  • 打赏
  • 举报
回复
这种题目给一只笔很多人会用正确的算法。

给一台电脑可能很多人的算法就不咋样了
AJrxin 2009-09-14
  • 打赏
  • 举报
回复
看看
wenzheng38 2009-09-14
  • 打赏
  • 举报
回复
//编程之美上面的
int factor = 1;
int lowNum = 0;
int curNum = 0;
int higNum = 0;
while(n / factor != 0){
lowNum = n - (n / factor)*factor;
curNum = (n / factor)%10;
higNum = n / (factor*10);

switch(curNum){
case 0:
count += higNum * factor;
break;
case 1:
count += higNum * factor + lowNum + 1;
break;
default:
count += (higNum + 1)*factor
break;
}
factor *= 10;
}
return count;
cattycat 2009-09-13
  • 打赏
  • 举报
回复
此题就是编程之美上的。
showjim 2009-09-13
  • 打赏
  • 举报
回复
        public static int count1(int number)
{
int value = 0;
if (number > 0)
{
int mod = number % 10;
value = (number /= 10) + ((mod + 15) >> 4);
for (int nextMod, mul = 10; number > 0; mul *= 10)
{
nextMod = number % 10;
value += (number /= 10) * mul;
if (nextMod > 1) value += mul;
else if (nextMod == 1) value += mod + 1;
mod += nextMod * mul;
}
}
return value;
}
Dolphin_001 2009-09-13
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 legend115599 的回复:]
引用 5 楼 dolphin_001 的回复:
有個地方說錯了,故得出结论,假设第N位的数为b,当b大于1时,那么第N位1的个数为,10^n + (b - 2)a(n - 1); 要改成^n + (b - 1)a(n - 1); 后面的編程沒錯.
此题不用递归不行的,不知是否是楼主要求的.

为什么说不用递归是不行的呢?
这道题其实是《编程之美》中的一个例子,里面的解法直接通过处理N,就可以得到结果,时间复杂度极低,为0(len(N))
[/Quote]
用递归是M位递归,显然比楼主的len(N)复杂度低多了,M位递归的时间复杂度为O((1+M)M/2),比如1032,按照你的算法,要遍历1032次,按照M位递归,只需要10次.
绿色夹克衫 2009-09-12
  • 打赏
  • 举报
回复
这题讨论过很多次了,LZ可以看看以前的帖子,方法很多!

http://topic.csdn.net/u/20071101/23/03C40ABB-CC82-450C-8781-FC121E616BA6.html

[Quote=引用楼主 legend115599 的回复:]
给定一个十进制正整数N,写下从1开始,到N的所有正数,然后数出其中出现所有1的个数。
那种循环套嵌浪费一摩尔多时间的常规算法就不要来了哈,人家要的是效率
[/Quote]
acdbxzyw 2009-09-12
  • 打赏
  • 举报
回复
這都不會?
按個位十位百位這麼數來的。
legend115599 2009-09-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dolphin_001 的回复:]
有個地方說錯了,故得出结论,假设第N位的数为b,当b大于1时,那么第N位1的个数为,10^n + (b - 2)a(n - 1); 要改成^n + (b - 1)a(n - 1); 后面的編程沒錯.
此题不用递归不行的,不知是否是楼主要求的.
[/Quote]
为什么说不用递归是不行的呢?
这道题其实是《编程之美》中的一个例子,里面的解法直接通过处理N,就可以得到结果,时间复杂度极低,为0(len(N))
Dolphin_001 2009-09-12
  • 打赏
  • 举报
回复
有個地方說錯了,故得出结论,假设第N位的数为b,当b大于1时,那么第N位1的个数为,10^n + (b - 2)a(n - 1); 要改成^n + (b - 1)a(n - 1); 后面的編程沒錯.
此题不用递归不行的,不知是否是楼主要求的.
Dolphin_001 2009-09-12
  • 打赏
  • 举报
回复
[Quote=引用楼主 legend115599 的回复:]
出现所有1的个数。
[/Quote]
楼主,这句话,是指数字的所有位是1?(比如111)还是数字包含1?(比如12)还是数字包含了1的所有位数?(比如121算2个)。
每种都可以用数学归纳法来做。楼主应该是说第二种吧,我们以第二种来讨论吧
以数列a(0),a(1)。。。a(n)表示,个位,十位。。。N位数总共含有的1个数。
因为个位数为,0,1,2。。。9,故a(0) = 1= 10^0 + 0;(我们另a(-1) = 0;故a(0) = 10^0 + 9a(-1))
十位数为0,1,2。。。9,10,11,12。。。19,21。。。91。。99;a(1) = a(0) + 10 + (10 - 2)a(1) = 10^1 + 9a(0);
百位数为0,1,2。。。9,10,11,12。。。19,21。。。91。。99,100,101,102。。。109,110,111,112。。119,121。。。191。。。991。。999.故a(2) = a(1) + 100 + (10 - 2)a(1) = 10^2 + 9a(1);
故推出a(n) = 10^n + 9a(n - 1);
以1363为例,他是由个位1,十位1,百位1组成的,各位1个数为1 = 10^0 + (3 - 2)a(-1);
十位的1为a(0) + 10^1 + (6 -2)a(0) = 10^1 + (6 – 1)a(0);
百位的1为a(1) + 10^2 + (3 – 2)a(1) = 10^2 + (3 – 1)a(1);
千位的1为10^2 + 9a(2 - 1) + 363 + 1;

故得出结论,假设第N位的数为b,当b大于1时,那么第N位1的个数为,10^n + (b - 2)a(n - 1);
当b等于1时,那么比他低位的数因为含有1,之前算的总数必须改成低位的总数目,
第N位1的个数为,10^(n-1) + 9a(n - 2) + num;(num为比N位低的位数的总数)
具体编程:
#include <iostream.h>
#include <math.h>
int f(int n)
{
if (-1 == n) return 0;
return pow(10, n) + 9*f(n - 1);
}

int OneCount(int x)
{
int i,Num, Count = 0, Bit = 0;
int Temp = x;//记下原始数
while(x > 0)
{
i = x % 10;
if (1== i)
{
Num = Temp - x*pow(10, Bit) + 1;//num为低位的位数总数,比如6120,此时的位数总数为21.
Count = pow(10, (Bit - 1)) + 9*f(Bit - 2) + Num;//计算第Bit位1的总数.
}
else if ( i > 1)//该位大于一时,那么第Bit位1的总数为,10^n + (b - 2)a(n - 1);
{
Count += pow(10, Bit) + (i - 1)*f(Bit - 1);
}
Bit++;
x = x / 10;
}
return Count;
}

int main()
{
int Num,Count;
cin>>Num;
cin.peek();
Count = OneCount(Num);
cout<<Count<<endl;
cin.peek();
return 0;
}

輸入100,輸出20.
輸入6120,輸出2395s


zhengyanming3 2009-09-12
  • 打赏
  • 举报
回复
用求组合的思想试试.如一位数的时候,只有1,二位数的时候有:1X,X1,三位数的时候有1XX,X1X,XX1,....依些类推.

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧