新坑 Leet Code DP(动态规划)题解总和

     毕业老,挖新坑,同学推荐了一个Leet Code OJ给我,之前搞ACM我最喜欢做DP题,所以对于新OJ,我想说的是,DP题就交给我吧。题目题解没有顺序,要查某题可以自行搜索,我还未解决的可以留言提醒我去搞定。顺带一提我这次做题准备全用JAVA来做。


P303. Range Sum Query - Immutable

题解:题目大一为给定一个数组,给出一些问题,让我们求出区间和,如果用O(n^2)的方法会非常直观,但是效率不高,其实我们只要做一个预处理,每个问题就能够在O(1)的时间内解出。因为Range(i,j)=Sum[j]-Sum[i-1]{sum[i]为数组前几个数字的和}。所以预处理就是做数组前几数和的过程。总体来说是一道简单题。

参考代码:

public class NumArray {
    private int[] sum;
    public NumArray(int[] nums) {
      int l=nums.length;
      if(l!=0){
      sum=new int[l];
      sum[0]=nums[0];
      for(int i=1;i


P368. Largest Divisible Subset

题解:题目大意为一个非负数字集合,没有重复的数字。求一个最长的子集,子集中任意两数要满足大的数要整除小的数。基本的DP题型,这道题时间复杂度要求不高,用n(O^2)的方法即可AC,首先先将数组排序,dp[i][1]代表数组中前i个数中最长的子集。由于当a整除b时,一定能保证整除b所有可以整除的其他数。所以转移方程就是

dp[i][1]=max(dp[i][1],dp[j][1]+1){i%j==0};然后dp[i][0]则用来记录它是由哪个j转移过来的,方便输出答案集合。具体详情请看参考代码。

参考代码:

public class Solution {
    public static List largestDivisibleSubset(int[] nums) {
      List re=new ArrayList();
      if(nums.length==0) return re;
      if(nums.length==1){
        re.add(nums[0]);
        return re;
      }
      Arrays.sort(nums);
      int l=nums.length;
      int[][] dp=new int[l+1][2];
      dp[0][1]=1; dp[0][0]=-1;
      for(int i=1;idp[i][1]){
          dp[i][1]=dp[j][1]+1;
          dp[i][0]=j;
        }
      } 
      int maxv=0,maxi=0;
      for(int i=0;imaxv){
        maxv=dp[i][1];
        maxi=i;
      }
      while(maxi!=-1){
        re.add(nums[maxi]);
        maxi=dp[maxi][0];
      }
      return re;
    }
}





你可能感兴趣的:(LeetCode,DP)