【题目】

输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。

【分析】

这是一道广为流传的google面试题。

普通n*lg(n)的解法。

【解法1】

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 
/////////////////////////////////////////////////////////////////////////////
// Find the number of 1 in an integer with radix 10
// Input: n - an integer
// Output: the number of 1 in n with radix
/////////////////////////////////////////////////////////////////////////////
int NumberOf1(unsigned int n)
{
    ;
    while(n)
    {
        )
            number ++;

n = n / ;
    }

return number;
}

/////////////////////////////////////////////////////////////////////////////
// Find the number of 1 in the integers between 1 and n
// Input: n - an integer
// Output: the number of 1 in the integers between 1 and n
/////////////////////////////////////////////////////////////////////////////
int NumberOf1BeforeBetween1AndN_Solution1(unsigned int n)
{
    // T(n) = n*lg(n)
;

// Find the number of 1 in each integer between 1 and n
; i <= n; ++ i)
        number += NumberOf1(i);

return number;
}

【解法2】

更加巧妙的lg(n)的解法。

简单的方法就是按照给位进行分析:

在个位出现1的个数=n/10+(个位=0,0;个位>1,1;个位=1,低0位+1);

十位位出现1的个数=n/100*10+(十位=0,0;十位>1,10;十位=1,低一位+1);

百位出现1的个数=n/1000*100+(百位=0,0;百位>1,100;百位=1,低两位+1);

等等。

算法的复杂度仅仅和位数有关。

设第i位出现1的个数为s(i),N为输入整数n的位数。则总和sum= s(1)+…s(i)+…s(N)即为所求。

设bi为整数n的第i位数字,第i位之后的剩余数字为ri;

s(i) = A + B

A = n/10i*10i-1

bi=( n/10i-1)%10

ri= n/10i-1

b(i)==0 ,则B=0

b(i)==1 ,则B=ri+1

b(i)>1 ,则B=10i-1

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 
int PowerBase10(unsigned int n)
{
    // 10^n
;
    ; i < n; ++ i)
        result *= ;

return result;
}

int b10(unsigned int n)
{
    return PowerBase10(n);
}

int NumberBitCount(unsigned int n)
{
    ;
    while(n)
    {
        n = n / ;
        N++;
    }
    return N;
}

int NumberOf1BeforeBetween1AndN_Solution2(unsigned int n)
{
    // T(n) = o(N) = o(lgn)
    int N = NumberBitCount(n);
    ;
    int A, B, bi, ri;
    ; i <= N; i++)
    {
        A = n / b10(i) * b10(i - );
        bi = n / b10(i - ;
        ri = n % b10(i - );
        )
        {
            B = ;
        }
        )
        {
            B = ri + ;
        }
        )
        {
            B = b10(i - );
        }
        si = A + B;
        sum += si;
    }

return sum;
}

【参考】

http://zhedahht.blog.163.com/blog/static/25411174200732494452636/

http://www.cnblogs.com/GoAhead/archive/2012/05/28/2521415.html

http://blog.csdn.net/sjf0115/article/details/8600599

25.在从1到n的正数中1出现的次数[NumberOf1Between1_N]的更多相关文章

  1. 【编程题目】在从 1 到 n 的正数中 1 出现的次数

    30.在从 1 到 n 的正数中 1 出现的次数(数组)题目:输入一个整数 n,求从 1 到 n 这 n 个整数的十进制表示中 1 出现的次数.例如输入 12,从 1 到 12 这些整数中包含 1 的 ...

  2. Google面试题:计算从1到n的正数中1出现的次数

    题目: 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次. 找工作,准备看写题目,题目说是Goo ...

  3. 在从1到n的正数中1出现的次数

    #include <iostream> using namespace std; int cal1From0ToN(int n) { int pow1 = 1; int pow2 = 10 ...

  4. 【google面试题】求1到n的正数中1出现的次数的两种思路及其复杂度分析

    问题描写叙述: 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.比如输入12,从1到12这些整数中包括1 的数字有1.10.11和12.1一共出现了5次. 这是一道广为流传的googl ...

  5. 在从1到n的正数中1出现的次数 【微软面试100题 第三十题】

    题目要求: 给定 一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数.    例如:N = 2,写下1,2.这样只出现了1个“1”.          N = 12 ...

  6. L2-006 树的遍历 (25 分) (根据后序遍历与中序遍历建二叉树)

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805069361299456 L2-006 树的遍历 (25 分 ...

  7. 从给定的N个正数中选取若干个数之和最接近M

    https://blog.csdn.net/lsjseu/article/details/11660731

  8. 九度OJ 1373 整数中1出现的次数(从1到n整数中1出现的次数)

    题目地址:http://ac.jobdu.com/problem.php?pid=1373 题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU ...

  9. 算法练习26-xx

    26.左旋转字符串(字符串) 题目:定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部. 如把字符串abcdef左旋转2位得到字符串cdefab.请实现字符串左旋转的函数.要求时间对长 ...

随机推荐

  1. 小菜鸟学 MQ(一)

    第一步: 从http://activemq.apache.org/ 下载相关文件. apache-activemq-5.8.0-bin.zip 解压到指定目录下. 第二步: cmd 下切换到   mq ...

  2. Java-日期转换

    如下: package 时间日期类; import java.text.SimpleDateFormat; import java.util.Date; public class 日期格式转换 { / ...

  3. JAVA运行java程序

    程序代码: public class f{ public static void main(String[] args){ String foo1 = args[1]; String foo2 = a ...

  4. 后台管理UI推荐

    目录 一.EasyUI 二.DWZ JUI 三.HUI 四.BUI 五.Ace Admin 六.Metronic 七.H+ UI 八.其它UI 九.总结 最近要做一个企业的OA系统,以前一直使用Eas ...

  5. linux中为什么已经是root用户仍不能执行程序

    .sh文件 ,获取root权限,提示Permission Denied. 这是因为文件本身没有可执行特性. chmod +x a.sh chmod 755 a.sh

  6. 巧用section在cshtml写入layout中写入head信息 ASP.NET MVC

    转自:http://www.cnblogs.com/a-xu/archive/2012/05/08/2489746.html layout文件中: <head> <meta char ...

  7. easyui form submit 不提交

    http://bbs.csdn.net/topics/390811964 function saveProduct() {             //$('#fm').form('submit',  ...

  8. MyEclipse------随机流(能读也能写数据)

    RandomAccessFile流指向文件时,不刷新文件. 其中seek(long a)用来定位RandomAccessFile流的读写位置,其中参数a确定读写位置距离文件开头的字节个数. other ...

  9. while练习:输入一个班级的人数,然后依次输入学员成绩,计算班级学员的平均成绩和总成绩。

    Console.WriteLine("请输入班级的总人数:"); int count = int.Parse(Console.ReadLine()); ;//声明一个循环变量来记录 ...

  10. Sql Server中启用分布式事务小结

    1.web服务器与数据库服务器同时启动msdtc服务 2. 2台服务器做出如下配置: 控制面板->管理工具->组件服务->计算机->我的电脑->本地DTC .Net示例: ...