斐波那契
先用递归写,空间复杂度2^n,指数爆炸,然后换dp写法,把每次运算结果储存起来,省去大量计算,空间复杂度降低,然后换掉数组,就两个值来回切换,空间复杂度直接O(1)。
public class dp斐波那契 {
public static void main(String[] args) {
System.out.println(fib(30));
System.out.println(fibDp(3000));
}
// 直接使用递归的斐波那契数列,时间复杂度O(2^n)
public static int fib(int N) {
if (N == 1 || N == 2)
return 1;
else
return fib(N - 1) + fib(N - 2);
}
// 带【备忘录】的斐波那契数列,时间复杂度O(n)
public static int fibDp(int N) {
int arr[] = new int[N + 1];
for (int i = 0; i < arr.length; i++)
arr[i] = 0;
return helper(arr, N);
}
public static int helper(int[] arr, int n) {
if (n == 1 || n == 2)
return 1;
if (arr[n] != 0)
return arr[n];
arr[n] = helper(arr, n - 1) + helper(arr, n - 2);
return arr[n];
}
// 将步骤整合为
public static int dpTable(int m) {
int dpTable[] = new int[m + 1];
for (int i = 0; i < dpTable.length; i++)
dpTable[i] = 0;
if (m == 1 || m == 2)
return 1;
if (dpTable[m] != 0)
return dpTable[m];
dpTable[m] = helper(dpTable, m - 1) + helper(dpTable, m - 2);
return dpTable[m];
}
// 状态压缩,空间复杂度为O(1)
public static int dp(int x) {
if (x < 0)
return 0;
if (x == 1 || x == 2)
return 1;
int prev = 1, curr = 1;
for (int i = 3; i <= x; i++) {
int sum = prev + curr;
prev = curr;
curr = sum;
}
return curr;
}
}
零钱兑换
力扣322题,初练dp用这个还是很不错的,