版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kurozaki_Kun/article/details/79650985
题目来源:网易
我的解法:
一开用的是始逐项求最大奇数然后相加的解法,由于后面几个测试用例的n比较大,所以运行超时了,这样就不得不从中找规律来解。
不难发现,当x为奇数时,f(x)=x。
当n为奇数,s(n) = f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + .... + n = (1 + 3 + 5 + 7 + ...+ n) + (f(2) + f(4) + f(6) + ... + f(n- 1))
令k = (n+1)/2, 根据等差数列的性质
s(n) = k*(1 + n)/2 = k^2 + (2 + 4 + 6 + .. + n-1) = k^2 + (f(1) + f(2) + f(3) + ... +f((n-1)/2))
s(n) = k^2 + s((n-1)/2) = k ^ 2 + s(n/2) (这里因为n为奇数,除法只取整数部分,因此(n-1)/2和n/2是一样的)
当n为偶数,能够得出同样的递推公式。
显然,这个算法的时间复杂度从原本的O(n)降到了O(logn)。
代码实现
public class LuckyNumber {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
System.out.println(oddSum(n));
}
public static long oddSum(int n) {
if (n == 0) {
return 0;
}
long k = (n + 1) >> 1;
return k * k + oddSum(n / 2); //如果不用递归,这段也能转化成循环
}
}