一、记忆化搜索
斐波那契算法
1.递归代码(时间复杂度O(2^n)):
int f(int n){ if(n == 1 || n == 2){ return 1; } return f(n-1) + f(n-2); }
2.递归加记忆化
public class Solution{
int[] res = new int[n]; Arrays.fill(res, -1);
int f(int n){ if(n == 1 || n == 2){ return 1; } if(res[n] == -1) return f(n-1) + f(n-2);
return res[n]; }
}
3.动态规划 或者 转化为非递归 或者转化为矩阵求解
递归是自上而下的解决问题(如求f(n)就已经假设所有小于n的值已经得到,)
动态规划是自下而上的解决问题(求f(n) 就已经把前面n-1个值完全获得)
动态规划 约等于 记忆化搜索 (严格来说不对 因而 记忆化搜索也是自上而下,动态规划是自下而上的解决问题 )
70. Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
Example 1:
Input: 2 Output: 2 Explanation: There are two ways to climb to the top. 1. 1 step + 1 step 2. 2 steps
代码如下:
class Solution { public int climbStairs(int n) { if(n ==1 || n ==2){ return n; }else{ int[] arr = new int[n]; arr[0] = 1; arr[1] = 2; for(int i = 2; i < n; i++) { arr[i] = arr[i-1] + arr[i-2]; } return arr[n-1]; } } }
120. Triangle
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
The minimum path sum from top to bottom is 11
(i.e., 2 + 3 + 5 + 1 = 11).
代码如下:
class Solution { public int minimumTotal(List<List<Integer>> triangle) { int[] re = new int[triangle.size() + 1]; for(int i=triangle.size()-1;i>=0; i--){ for(int j=0; j<triangle.get(i).size(); j++){ re[j] = Math.min(re[j],re[j+1]) + triangle.get(i).get(j);//re数组每次填充的值都是一样的 } } return re[0]; } }
64. Minimum Path Sum
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
Example:
Input: [ [1,3,1], [1,5,1], [4,2,1] ] Output: 7 Explanation: Because the path 1→3→1→1→1 minimizes the sum.
代码如下:
class Solution { public int minPathSum(int[][] grid) { for(int i=1; i<grid.length; i++) { grid[i][0] = grid[i-1][0] + grid[i][0]; } for(int j=1; j<grid[0].length; j++) { grid[0][j] = grid[0][j-1] + grid[0][j]; } for(int i=1; i<grid.length; i++) { for(int j=1; j<grid[0].length; j++) { grid[i][j] = Math.min(grid[i-1][j], grid[i][j-1]) + grid[i][j]; } } return grid[grid.length-1][grid[0].length-1]; } }
343. Integer Break
Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.
Example 1:
Input: 2 Output: 1 Explanation: 2 = 1 + 1, 1 × 1 = 1.
Example 2:
Input: 10 Output: 36 Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.
代码如下: