最近公司有程序员大赛,题目大概是这样的:
有数值类型 123, 每次去除末尾的一个字符 123 12 1 , 然后累加 123+12+1=136
程序输入 136,求是否存在这样一个数(如:123)每次去除末尾一个字符累加等于136,并求这个数的最小值,没有该数 返回 -1
一开始我的程序是这样写的:
public static long getVal(String line) {
long value = Long.parseLong(line);
long ret = -1;
long count = 0L;
String s = "";
for (long i=1; i <= value; i++) {
count = 0L;
s = String.valueOf(i);
for (int j=s.length(); j >= 1; j--) {
count += (i / Math.pow(10, j - 1));
if (count > value) {
break;
}
}
if (value == count) {
ret = i;
break;
}
}
return ret;
}
这是直接遍历的全部的数,后面发现运行超时了好长好长.............
可能之前对算法这一块还是建立在学习的层面,还没有到应用的层面,所以没有想到 二分法查找,
二分法的前提是 遍历查找的这一串数值是有序的,如果是散列的话,是无法使用二分法的(这是我现在对二分法的理解,如果不足或错误的地方,还请各位不吝赐教)
改进后的代码(二分法):
private static long decide(long x) {
long count = 0;
while(x > 0) {
count += x;
x /= 10;
}
return count;
}
private static String getVal(String line) {
long x = Long.parseLong(line);
long l = -1;
long r = x + 1;
while(l < r - 1) {
long mid = (l + r) / 2;
long tmp = decide(mid);
if (tmp > x)
r = mid;
else
l = mid;
}
// 返回处理后的结果
if(decide(l) == x)
return String.valueOf(l);
else
return "-1";
}