7、斐波那契数列
public class Solution {
public int Fibonacci(int n) {
if(n == 0) return 0;
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; i++){
dp[i] = dp[i-1] + dp[i-2];//动态规划
dp[i] %= 1000000007;
}
return dp[n];
}
}
优化后空间复杂度O(1)
class Solution {
public int fib(int n) {
int a = 0, b = 1, sum;
for(int i = 0; i < n; i++){
sum = (a + b) % 1000000007;
a = b;
b = sum;
}
return a;
}
}
8、跳台阶
class Solution {
public int numWays(int n) {
int a = 1, b = 1, sum;//考虑一下第一个和第二个初始值
for(int i = 0; i < n; i++){//i<n是刚好返回i==n的状态
sum = (a + b) % 1000000007;
a = b;
b = sum;
}
return a;//数一数应该返回多少
}
}
9、变态跳台阶
因为n级台阶,第一步有n种跳法:跳1级、跳2级、到跳n级
跳1级,剩下n-1级,则剩下跳法是f(n-1)
跳2级,剩下n-2级,则剩下跳法是f(n-2)
所以f(n)=f(n-1)+f(n-2)+…+f(1)
因为f(n-1)=f(n-2)+f(n-3)+…+f(1)
所以f(n)=2*f(n-1)
public class Solution {
public int jumpFloorII(int target) {
if (target <= 0) {
return -1;
} else if (target == 1) {
return 1;
} else {
return 2 * jumpFloorII(target - 1);
}
}
}
10、矩形覆盖
public class Solution {
public int rectCover(int n) {
if (n==0 || n==1 || n==2) return n;//前面的特例
int a = 1, b = 2, c=0;
for (int i=3; i<=n; ++i) {
c = a + b;//3=1+2
a = b;//1=2
b = c;//3=2
}
return c;//返回第三位置
}
}
12、数值的整数次方
class Solution {
public double myPow(double x, int n) {
if(n == 0) return 1;
if(n == 1) return x;
if(n == -1) return 1 / x;
double half = myPow(x, n / 2);
double mod = myPow(x, n % 2);
return half * half * mod;
}
}
47、求1+2…+n
public class Solution {
public int Sum_Solution(int n) {
boolean x = n > 1 && Sum_Solution(n - 1) > 0; //只要循环体内n>1,就一直循环。当 n = 1 时 n > 1 不成立 ,此时 “短路” ,终止后续递归。否则执行递归
res += n;
return res;
}
}
48、不用加减乘除做加法
首先看十进制是如何做的: 5+7=12,三步走
第一步:相加各位的值,不算进位,得到2。
第二步:计算进位值,得到10. 如果这一步的进位值为0,那么第一步得到的值就是最终结果。
第三步:重复上述两步,只是相加的值变成上述两步的得到的结果2和10,得到12。
同样我们可以用三步走的方式计算二进制值相加: 5-101,7-111 第一步:相加各位的值,不算进位,得到010,二进制每位相加就相当于各位做异或操作,101^111。
第二步:计算进位值,得到1010,相当于各位做与操作得到101,再向左移一位得到1010,(101&111)<<1。
第三步重复上述两步, 各位相加 010^1010=1000,进位值为100=(010&1010)<<1。
继续重复上述两步:1000^100 = 1100,进位值为0,跳出循环,1100为最终结果。
public class Solution {
public int Add(int num1,int num2) {
while (num2!=0) {// 当进位为 0 时跳出
int temp = num1^num2;// 异或 非进位和
num2 = (num1&num2)<<1; //进位 与
num1 = temp; //如果还有进位,再循环,如果没有,则直接输出没有进位部分即可。
}
return num1;
}
}