不同路径
一个机器人位于一个
m x n
网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7 输出:28
dfs
class Solution { public int uniquePaths(int m, int n) { return dfs(m,n); } public int dfs(int i,int j){ if(i==0||j==0) return 0; if(i==1&&j==1) return 1; return dfs(i-1,j)+dfs(i,j-1); } }
记忆化搜索
class Solution { int[][] memo; public int uniquePaths(int m, int n) { memo=new int[m+1][n+1]; return dfs(m,n); } public int dfs(int i,int j){ if(memo[i][j]!=0){ return memo[i][j]; } if(i==0||j==0) return 0; if(i==1&&j==1) return 1; memo[i][j]=dfs(i-1,j)+dfs(i,j-1); return memo[i][j]; } }
dp
class Solution { public int uniquePaths(int m, int n) { int[][]dp=new int[m+1][n+1]; dp[1][1]=1; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(i==1&&j==1) continue; dp[i][j]=dp[i-1][j]+dp[i][j-1]; } } return dp[m][n]; } }
class Solution { public int uniquePaths(int m, int n) { int[][]dp=new int[m+1][n+1]; dp[0][1]=1; for(int i=0;i<=m;i++){ for(int j=0;j<=n;j++){ if(i!=0&&j!=0) dp[i][j]=dp[i-1][j]+dp[i][j-1]; } } return dp[m][n]; } }
在动态规划的题中需要注意,(会越界的位置)对数组大小进行调整后对应的映射问题:
下降路径最小和·
输入:matrix = [[2,1,3],[6,5,4],[7,8,9]] 输出:13 解释:如图所示,为和最小的两条下降路径class Solution { public int minFallingPathSum(int[][] nums) { int m=nums.length;int n=nums[0].length; int[][] dp=new int[m+1][n+2];//上加1行,左右各 加一列 for(int i=1;i<=m;i++) dp[i][n+1]=dp[i][0]=Integer.MAX_VALUE; int ret=Integer.MAX_VALUE; for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) dp[i][j] = nums[i - 1][j - 1] + Math.min(Math.min(dp[i - 1][j], dp[i - 1][j - 1]), dp[i - 1][j + 1]); for(int i=0;i<n+1;i++){ ret=Math.min(dp[m][i],ret); } return ret; } }
最小路径和
示例 1:
输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 输出:7 解释:因为路径 1→3→1→1→1 的总和最小最后才发现我错误的原因是初始化错了我
class Solution { public int minPathSum(int[][] nums) { int m = nums.length; int n = nums[0].length; int[][] dp = new int[m+1][n+1]; for(int i=2;i<=n;i++) dp[0][i]=Integer.MAX_VALUE; for(int j=2;j<=m;j++) dp[j][0]=Integer.MAX_VALUE; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + nums[i-1][j-1];//越界访问 } } return dp[m][n]; } }
最长递增子序列
中等
3.5K
相关企业
给你一个整数数组
nums
,找到其中最长严格递增子序列的长度。子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,
[3,6,2,7]
是数组[0,3,1,6,2,2,7]
的子序列。示例 1:
输入:nums = [10,9,2,5,3,7,101,18] 输出:4 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。示例 2:
输入:nums = [0,1,0,3,2,3] 输出:4示例 3:
输入:nums = [7,7,7,7,7,7,7] 输出:1
dfs
class Solution {int n; public int lengthOfLIS(int[] nums) { n=nums.length;int ret=0; for(int i=0;i<n;i++){ ret=Math.max(ret,dfs(i,nums)); } return ret; } public int dfs(int pos,int[] nums){ int ret=1; for(int i=pos+1;i<n;i++){ if(nums[pos]<nums[i]){ ret=Math.max(ret,dfs(i,nums)+1); } } return ret; } }
记忆化搜索
class Solution {int n; public int lengthOfLIS(int[] nums) { n=nums.length;int ret=0;int[] memo=new int[n]; for(int i=0;i<n;i++){ ret=Math.max(ret,dfs(i,nums,memo)); } return ret; } public int dfs(int pos,int[] nums,int[] memo){ if(memo[pos]!=0) return memo[pos]; int ret=1; for(int i=pos+1;i<n;i++){ if(nums[pos]<nums[i]){ ret=Math.max(ret,dfs(i,nums,memo)+1); } } memo[pos]=ret; return memo[pos]; } }
dp
class Solution { public int lengthOfLIS(int[] nums) { int ret=0; int[] dp=new int[nums.length]; Arrays.fill(dp,1); for(int i=nums.length-1;i>=0;i--){ for(int j=i+1;j<nums.length;j++){ if(nums[j]>nums[i]) dp[i]=Math.max(dp[i],dp[j]+1); } ret=Math.max(ret,dp[i]); } return ret; } }