zoukankan      html  css  js  c++  java
  • [转]微软面试题求出1的个数之小解

    原题目:
     给定一个十进制数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有"1"的个数。
     例如:
     N=2,写下1,2。这样只出现了1个"1"
     N=12,写下 1,2,3,4,5,6,7,8,9,10,11,12。这样"1"的个数是5
     请写出一个函数,返回1到N之间出现"1"的个数,比如 f(12)=5

    代码
     1package org.blogjava.arithmetic;
     
    2
     
    3/**//**
     4 * @author Jack.Wang
     5 * @see 
    http://jack2007.blogjava.net/
     6 
    */
     7
    public class CountNumber {
     
    8
     
    9    private int count1Num(int num) {
    10        int sum = 0;
    11        while (num != 0) {
    12            sum += (num % 10 == 1? 1 : 0;
    13            num /= 10;
    14        }
    15        return sum;
    16    }
    17
    18    private int countNum(int n) {
    19        int sum = 0;
    20        for (int i = 1; i <= n; i++) {
    21            sum += count1Num(i);
    22        }
    23        return sum;
    24    }
    25
    26    private int countNumNew(int n) {
    27        int count = 0;
    28        int factor = 1;
    29        int lower;
    30        int current;
    31        int higher;
    32        while (n / factor != 0) {
    33            lower = n - (n / factor) * factor;
    34            current = (n / factor) % 10;
    35            higher = n / (factor * 10);
    36            switch (current) {
    37            case 0:
    38                count += higher * factor;
    39                break;
    40            case 1:
    41                count += higher * factor + lower + 1;
    42                break;
    43            default:
    44                count += (higher + 1* factor;
    45            }
    46            factor *= 10;
    47        }
    48        return count;
    49    }
    50
    51    /**//**
    52     * @param args
    53     
    */
    54    public static void main(String[] args) {
    55        System.out.println("两个算法的结果相等");
    56        /**//**
    57         * 方法一: 这个问题看上出并不是一个难问题,因为不需要太多的思考,只要稍懂点程序的人都会想到,简单的设计如下。
    58         * 这个方法很简单但是这个算法的致命问题是效率,它的时间复杂度是 O(N)*count(int num)函数的复杂度=
    59         * O(N)*logN。可见如果N很大时复杂度成线性增长。是否还有更好的方法,我说的是从算法复杂的角度考虑最优的方法? 
                        请看方法二。
    60         
    */
    61        long start = System.currentTimeMillis();
    62        CountNumber cn1 = new CountNumber();
    63        System.out.println("第一个算法的结果"+cn1.countNum(100000000));
    64        long end = System.currentTimeMillis();
    65        long time1 = end - start;
    66        /**//**
    67         * 方法二: 这种方法分别分析N的每一位上1出现的可能性,读者可以自己按照归纳的思想分析一下,最终你会得出
    68         * 一个结论,就是通过分析N而不是遍历1到N的每一个数就可以得出答案,如果N的长度为Len的话这种 算法的复杂度为O
                        (Len)。 发现规律为
    69         * 1. 如果位数上为0,1的数目由该位以上的数决定,并乘以该位的分位 比如百位上是0,高位上是14则百位上出现1的数目
                            为 14*100。
    70         * 2. 如果位数上为1,1的数目由高位和低位共同决定。 比如高位是14低位是112,则百位出现1的数目为 14×100+(112+
                            1) 
    71         * 3. 如果位数上大于1,则百位出现1的数目为 (14+1)×100
    72         
    */
    73        start = System.currentTimeMillis();
    74        CountNumber cn2 = new CountNumber();
    75        System.out.println("第二个算法的结果"+cn2.countNumNew(100000000));
    76        end = System.currentTimeMillis();
    77        long time2 = end - start;
    78        System.out.println("第一个算法的时延比第二个算法的多" + (time1 - time2) / 1000 + "");
    79    }
    80
    81    /**//**
    82     Console Out:
    83     两个算法的结果相等
    84     80000001
    85     80000001
    86     第一个算法的时延比第二个算法的多27秒
    87     
    */
    88}
    89

    原帖地址:

    http://www.blogjava.net/Jack2007/archive/2008/10/16/234742.html

  • 相关阅读:
    如何创建一个WebService
    javascript调用WebService Hello World
    音频处理介绍(Linux手机)
    Android开机画面大整容
    android 源代码结构
    移植 android, touch screen 不能正常工作的问题
    为 Linux 应用程序编写 DLL
    6410 声卡wm9713 驱动分析
    android bootload源码网址
    fprintf 控制台代码,可以控制光标等,控制台显示时间源码
  • 原文地址:https://www.cnblogs.com/4kapple/p/1955345.html
Copyright © 2011-2022 走看看