我有一个问题:
考虑一个函数,对于给定的整数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(不需要代码)。我们怎样才能在更短的时间内解决这个问题?
答案 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
所以1 + 1 + 9 + 9 = 20
检查你的答案,然后花费并测试你的逻辑。
因此,对于每一百个我们需要至少十个1,现在高达1000和100,000 在进一步探索这个系列之后,你最终会想出一个算法来确定所需的系列而不会循环所有的数字。