题目地址:
https://www.lintcode.com/problem/find-the-numbers/description
给定一个数 n n n,考虑一个斐波那契数列,以 0 , 1 0,1 0,1开头。问该数列的最靠近 n n n的比 n n n小和比 n n n大的数分别是多少。如果 n < 0 n<0 n<0则返回空数组,如果小于 n n n的数不存在则只返回那个比 n n n大的数。
思路是递推,同时开两个变量记录小于 n n n的数 x x x和大于 n n n的数 y y y,遇到小于 n n n的数则覆盖 x x x,遇到大于 n n n的数则赋值给 y y y并做标记,以后不再赋值。代码如下:
public class Solution {
/**
* @param n: the integer
* @return: the numbers that larger and smaller than `n`
*/
public int[] getNumbers(int n) {
// Write your code here
if (n < 0) {
return new int[0];
}
int[] dp = {0, 1};
int less = Integer.MAX_VALUE, more = 0;
boolean moreFound = false;
int idx = 0;
// dp[idx & 1]存的是递推的时候的两者较小的数
while (dp[idx & 1] <= n) {
int tmp = dp[idx + 1 & 1];
dp[idx & 1] += dp[idx + 1 & 1];
dp[idx + 1 & 1] = tmp;
if (dp[idx & 1] > n && !moreFound) {
more = dp[idx & 1];
moreFound = true;
}
if (dp[idx + 1 & 1] < n) {
less = dp[idx +1& 1];
}
idx++;
}
if (less < n) {
return new int[]{less, more};
} else {
return new int[]{more};
}
}
}
时间复杂度 O ( log n ) O(\log n) O(logn),空间 O ( 1 ) O(1) O(1)。