用于计算从1到n的数量的替代解决方案

时间:2014-02-07 15:15:43

标签: java

我有一个问题:

  

考虑一个函数,对于给定的整数n,它返回写出0和n(包括)之间的所有数字时所需的数量,例如,f(13)= 6。请注意,f(1)= 1。下一个最大的n是什么,f(n)= n?

为了找到这个答案,我按如下方式编写了一个程序:

/**
 * @author Rakesh KR
 *
 */
public class CountOne {

    public static int countOne(int n){
        int          count;
        StringBuffer strBff = new StringBuffer();
        for(int i=0;i<=n;i++){
            strBff = strBff.append(i);
        }
        count  = strBff.length() - strBff.toString().replace("1", "").length();
        strBff = null;
        return count;
    }

    public static void main(String[] args) {
        int count = 0;
        for(int i=1;i>0;i++){
            if(countOne(i)==i){
                System.out.println("Got it At :: "+ i);
                count++;
            }
            if(count==2)
                break;
        }
    }
}

程序运行正常。等了大约1个小时后,我得到了答案199981

我正在为这个问题寻找替代IDEA(不需要代码)。我们怎样才能在更短的时间内解决这个问题?

3 个答案:

答案 0 :(得分:3)

算术运算比转换为字符串和比较字符更有效。 此代码在不到10毫秒的时间内找到解决方案:

public class CountOne {

    public static int countOne(int n) {
        int count = 0;
        int mod;
        while (n > 0) {
            mod = n % 10;
            n /= 10;
            if (mod == 1) {
                count++;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        int sum = 1;
        for (int i = 2;; i++) {
            sum += countOne(i);
            if (sum == i) {
                System.out.println(i);
                break;
            }
        }
    }
}

答案 1 :(得分:2)

这将返回您正确的&#34;通过缓存先前的值

几乎立即获得价值
private static Integer prev = null;

public static int countOneDigit(int num) {
    String s = String.valueOf(num);
    if (s.indexOf('1') < 0) {
        return 0;
    }
    int count = 0;
    for (char c : s.toCharArray()) {
        switch (c) {
        case '1':
            count++;
        }
    }
    return count;
}

public static int countOne(int n) {
    int count = 0;
    if (prev != null) {
        prev += countOneDigit(n);
        return prev;
    }
    for (int i = 1; i <= n; i++) {
        count += countOneDigit(i);
    }
    prev = count;
    return count;
}

答案 2 :(得分:0)

不是循环所有数字,而是使用可以确定所需数量为1的算法,对于此类算法,您必须查看并识别数字序列中的模式。

例1-100

  • First Number需要1
  • 最后号码需要1
  • 第二行(11-19)
  • 中每个数字都有一个1
  • 每行有一个1(已经计算出第2行)(21,31,41,51,61,71,81,91)

所以1 + 1 + 9 + 9 = 20

检查你的答案,然后花费并测试你的逻辑。

因此,对于每一百个我们需要至少十个1,现在高达1000和100,000 在进一步探索这个系列之后,你最终会想出一个算法来确定所需的系列而不会循环所有的数字。