public int climbStairs(int n) { if(n<=1) return 1; int[] fibonacci=new int[n+2]; fibonacci[0]=0;fibonacci[1]=1; for(int i=2;i<=n+1;i++){ fibonacci[i]=fibonacci[i-1]+fibonacci[i-2]; } return fibonacci[n+1]; }
public int maxProfit(int[] prices) { if(prices.length<2) return 0; int[] minBefore=new int[prices.length]; minBefore[0]=prices[0]; for(int i=1;i
分析
定义:sum[i]表示nums[0]~nums[i]的和,i>=1
初始化:sum[0]=nums[0],便于边界处理
递归表达式:sum[i]=sum[i-1]+nums[i],i>=1
public class NumArray { private int[] nums; private int[] sumBefore; public NumArray(int[] nums) { this.nums=nums; if(nums.length!=0){ this.sumBefore=new int[nums.length]; solve(); } } public int sumRange(int i, int j) { if(nums.length==0) return 0; return nums[i]+sumBefore[j]-sumBefore[i]; } private void solve(){ sumBefore[0]=nums[0]; int sum=nums[0]; for(int i=1;i
public int numDecodings(String s) { if(s.length()==0)return 0; if(s.length()==1){ return s.charAt(0)=='0'?0:1; } int[] count=new int[s.length()]; count[0]=s.charAt(0)=='0'?0:1; if(s.charAt(1)!='0'){ count[1]+=count[0]; } if(s.charAt(0)=='1'||(s.charAt(0)=='2'&&s.charAt(1)<='6')){ count[1]+=1; } for(int i=2;i分析
public int lengthOfLIS(int[] nums) { if(nums.length==0) return 0; return maxLengthIncreasing(nums).size(); } public ListmaxLengthIncreasing(int[] a){ int[] d=new int[a.length]; //初始化 for(int i=0;i d[maxIndex]){ maxIndex=i; } } //解析结果 List res=new ArrayList (); res.add(a[maxIndex]); int nextIndex=maxIndex; for(int i=maxIndex-1;i>=0;i--){ if(d[i]+1==d[nextIndex]&&a[i]
public int maxSubArray(int[] nums) { if(nums.length==0) return 0; int[] d=new int[nums.length]; d[0]=nums[0]; for(int i=1;i方案二 我们确定需要一个数组来记录以每个位置结尾的序列的最大和吗?空间复杂度是否可以进行优化?
public int maxSubArray(int[] nums) { if(nums.length==0) return 0; int currentMax=nums[0],max=nums[0]; for(int i=1;i
//每一时刻,我们只需要保留当前的极值,只有极大值和极小值才可能组合成最终的结果 public int maxProduct(int[] A) { if (A.length == 0) { return 0; } int maxherepre = A[0]; int minherepre = A[0]; int maxsofar = A[0]; int maxhere, minhere; for (int i = 1; i < A.length; i++) { maxhere = Math.max(Math.max(maxherepre * A[i], minherepre * A[i]), A[i]); minhere = Math.min(Math.min(maxherepre * A[i], minherepre * A[i]), A[i]); maxsofar = Math.max(maxhere, maxsofar); maxherepre = maxhere; minherepre = minhere; } return maxsofar; }
public String longestPalindrome(String s) { if(s.length()==0) return ""; char[] cs=new char[s.length()*2+1]; cs[0]='*'; int index=1; for(int i=0;i=0&&end<=cs.length-1&&cs[start]==cs[end]){ if(end-start>maxEnd-maxStart){ maxEnd=end; maxStart=start; } start--; end++; } } StringBuilder builder=new StringBuilder(); for(int i=maxStart;i<=maxEnd;i++){ if(cs[i]!='*') builder.append(cs[i]); } return builder.toString(); }
public String longestPalindrome1(String s) { if(s.length()==0)return ""; char[] cs=new char[s.length()*2+1]; cs[0]='*'; int index=1; for(int i=0;imaxEnd-maxStart+1){ maxStart=row; maxEnd=col; } d[row++][col++]=true; }else{ d[row++][col++]=false; } } } StringBuilder builder=new StringBuilder(); for(int i=maxStart;i<=maxEnd;i++){ if(cs[i]!='*') builder.append(cs[i]); } return builder.toString(); }
public int minCut(String s) { int n=s.length(); if(s.length()<=1) return 0; //isPalin[i][j]=ture表示s[i]~s[j]是回文,否则不是 boolean[][] isPalin=new boolean[n][n]; //单个字符为回文 for(int i=0;i=0;i--){ for(int j=i+2;j There are a row ofnhouses, each house can be painted with one of the three colors: red, blue or green. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.
The cost of painting each house with a certain color is represented by a
nx3
cost matrix. For example,costs[0][0]
is the cost of painting house 0 with color red;costs[1][2]
is the cost of painting house 1 with color green, and so on... Find the minimum cost to paint all houses.Note: All costs are positive integers.
There are a row ofnhouses, each house can be painted with one of thekcolors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.
The cost of painting each house with a certain color is represented by a
nxk
cost matrix. For example,costs[0][0]
is the cost of painting house 0 with color 0;costs[1][2]
is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses.Note: All costs are positive integers.
Follow up: Could you solve it inO(nk) runtime?
分析
public int minCost(int[][] cost){ if(cost.length==0) return 0; int H=cost.length,C=cost[0].length; //d[i][j]表示h[i]刷c[j]时的h[0]~h[i]最小成本 int[][] d=new int[H][C]; for(int c=0;c最长公共子序列
public String lcs(String s,String t){ if(s.length()==0||t.length()==0){ return ""; } int m=s.length(),n=t.length(); int[][] d=new int[m+1][n+1]; //初始化 for(int i=0;i<=m;i++) d[i][0]=0; for(int j=0;j<=n;j++) d[0][j]=0; //迭代求解 for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(s.charAt(i-1)==t.charAt(j-1)){ d[i][j]=d[i-1][j-1]+1; }else{ d[i][j]=Math.max(d[i][j-1], d[i-1][j]); } } } //反向解析结果 StringBuilder res=new StringBuilder(); int row=m,col=n; while(row>=1&&col>=1){ if(s.charAt(row-1)==t.charAt(col-1)){ res.append(s.charAt(row-1)); row--;col--; }else{ if(d[row][col-1]>d[row-1][col]){ col--; }else{ row--; } } } return res.reverse().toString(); }
public String lcs(String s,String t){ if(s.length()==0||t.length()==0){ return ""; } int m=s.length(),n=t.length(); int[][] d=new int[m+1][n+1]; //初始化 for(int i=0;i<=m;i++) d[i][0]=0; for(int j=0;j<=n;j++) d[0][j]=0; int maxi=-1,maxj=-1,maxLength=Integer.MIN_VALUE; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(s.charAt(i-1)==t.charAt(j-1)){ d[i][j]=d[i-1][j-1]+1; if(d[i][j]>maxLength){ maxi=i;maxj=j;maxLength=d[i][j]; } }else{ d[i][j]=0; } } } if(maxi==-1){ return ""; }else{ return s.substring(maxi-maxLength,maxi); } }
public int numDistinct(String s, String t) { if(s.length()==0||t.length()==0||s.length()分析
public int minDistance(String word1, String word2) { if(word1.length()==0){ return word2.length(); } if(word2.length()==0){ return word1.length(); } int m=word1.length(),n=word2.length(); int[][] d=new int[m+1][n+1]; for(int i=0;i<=m;i++)d[i][0]=i; for(int j=0;j<=n;j++) d[0][j]=j; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(word1.charAt(i-1)==word2.charAt(j-1)){ d[i][j]=d[i-1][j-1]; }else{ d[i][j]=1+Math.min(d[i-1][j-1], Math.min(d[i-1][j], d[i][j-1])); } } } return d[m][n]; }
public boolean isInterleave(String s1, String s2, String s3) { if(s1.length()+s2.length()!=s3.length()){ return false; } int m=s1.length(),n=s2.length(),k=s3.length(); boolean[][] d=new boolean[m+1][n+1]; d[0][0]=true; for(int i=0;i<=m;i++){ for(int j=0;j<=n;j++){ if(i==0&&j==0){ continue; } if(i-1>=0&&d[i-1][j]&&s1.charAt(i-1)==s3.charAt(i+j-1)){ d[i][j]=true; } if(j-1>=0&&d[i][j-1]&&s2.charAt(j-1)==s3.charAt(i+j-1)){ d[i][j]=true; } } } return d[m][n]; }思考:如果是更一般的情况,s1和s2不是正好交替组合成s3,而是可能有多余的字符呢?
public boolean isInterleave(String s1, String s2, String s3) { if(s1.length()+s2.length()!=s3.length()){ return false; } //d[i][j]表示s1前i个字符和s2前j个能交替表示s3的前d[i][j]个字符 int m=s1.length(),n=s2.length(),k=s3.length(); int[][] d=new int[m+1][n+1]; for(int i=0;i<=m;i++){ for(int j=0;j<=n;j++){ int max=0; if((i>0&&d[i-1][j]>=k)||(j>0&&d[i][j-1]>=k)) max=k; if(i>0&&s1.charAt(i-1)==s3.charAt(d[i-1][j])){ max=Math.max(max, d[i-1][j]+1); } if(j>0&&s2.charAt(j-1)==s3.charAt(d[i][j-1])){ max=Math.max(max, d[i][j-1]+1); } d[i][j]=max; } } return d[m][n]==k; }
public int minMultiply(int[] a,int [] b){ int m=a.length,n=b.length; int[][] d=new int[m+1][n+1]; for(int i=1;i<=m;i++){ for(int j=i;j<=n;j++){ if(j==i){ d[i][j]=d[i-1][j-1]+a[i-1]*b[j-1]; }else{ d[i][j]=Math.min(d[i-1][j-1]+a[i-1]*b[j-1], d[i][j-1]); } } } return d[m][n]; }
public int minPathSum(int[][] grid) { if(grid.length==0||grid[0].length==0) return 0; int m=grid.length,n=grid[0].length; int[][] d=new int[m][n]; int sum=0; for(int i=0;i
public int uniquePaths(int m, int n) { if(m==0||n==0) return 1; int[][] d=new int[m][n]; for(int i=0;i
public int uniquePathsWithObstacles(int[][] obstacleGrid) { if(obstacleGrid.length==0&&obstacleGrid[0].length==0){ return 0; } if(obstacleGrid[0].length==0){ return 1; } int m=obstacleGrid.length,n=obstacleGrid[0].length; int[][] d=new int[m][n]; d[0][0]=(obstacleGrid[0][0]==1)?0:1; for(int i=1;i
public int minimumTotal(List<>> triangle) { if(triangle.size()==0||triangle.get(0).size()==0){ return 0; } int m=triangle.size(),n=m; int[][] d=new int[m][n]; int sum=0; for(int i=0;i 改进
public int minimumTotal(List<>> triangle) { if(triangle.size()==0||triangle.get(0).size()==0){ return 0; } int n=triangle.size(); int[] d=new int[n]; int[] pre=new int[n]; d[0]=triangle.get(0).get(0); for(int row=1;row
public int numTrees(int n) { if(n<=1)return 1; int[] nums=new int[n+1]; nums[0]=1;nums[1]=1; for(int i=2;i<=n;i++){ int sum=0; for(int j=0;j
public int longestConsecutive(int[] nums) { if(nums.length==0) return 0; MapmarkMap=new HashMap (); for(int i=0;i Map countMap=new HashMap (); for(int i=0;i
public int longestConsecutive(int[] nums) { if(nums.length==0) return 0; MaplengthMap=new HashMap (); for(int i=0;i max){ max=lengthMap.get(nums[i]); } } return max; } private void solveLength(int n,Map lengthMap){ if(lengthMap.get(n).equals(0)){//还没有处理过 if(lengthMap.get(n-1)!=null){//n-1存在,先处理n-1的连续长度 solveLength(n-1,lengthMap); lengthMap.put(n, lengthMap.get(n-1)+1); }else{ lengthMap.put(n, 1); } } }