新坑 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<l;i++)
        sum[i]=sum[i-1]+nums[i];
      }
    }

    public int sumRange(int i, int j) {
      if(i==0) return sum[j];
      return sum[j]-sum[i-1];
    }
}


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<Integer> largestDivisibleSubset(int[] nums) {
      List<Integer> re=new ArrayList<Integer>();
      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;i<l;i++){
        dp[i][1]=1; dp[i][0]=-1;
        for(int j=0;j<i;j++)
        if(nums[i]%nums[j]==0 && dp[j][1]+1>dp[i][1]){
          dp[i][1]=dp[j][1]+1;
          dp[i][0]=j;
        }
      } 
      int maxv=0,maxi=0;
      for(int i=0;i<l;i++)
      if(dp[i][1]>maxv){
        maxv=dp[i][1];
        maxi=i;
      }
      while(maxi!=-1){
        re.add(nums[maxi]);
        maxi=dp[maxi][0];
      }
      return re;
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值