动态规划,以LeetCode-CombinationSumIV问题为例
简介:
动态规划问题面试中经常遇到的问题之一,按照动态规划的一般定义,其一般解法在于将大问题分解为很多小问题去解决,但是我在遇到很多实际的问题时,想法都是强行的去将问题分解,而忽略了分解的必要性和途径的合理性。看某知乎大佬的帖子:动态规划的核心思想在于分解的小问题能否被上一级的问题去重用,也就是说我们在将大问题分解为小问题时,要考虑到求解出的小问题对于大问题的求解是否有一定的作用而且求解小问题的过程对大问题需要没有任何影响(像不像封装,似乎好多理论都是大同小异的,核心思想都很相似)。
例子:
以LeetCode-Combination Sum IV问题为例:
题目是这样描述的:
Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.
Example:
nums = [1, 2, 3]
target = 4 The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1) Note that different sequences are counted as different combinations. Therefore the output is 7. 是不是看起来感觉毫无难度,递归嘛,一层一层下去不就好了!所以我写出了递归求解思路:
private int combinationSum4_recur(int[] nums, int target){
int sum = 0;
for(int i : nums){
if(i == target) sum += 1;
else if(i < target) sum += combinationSum4_recur(nums, target - i);
}
return sum;
}
和我们用脑子解决这个问题的思路一模一样,然后就TLE了。。。
出错的例子:nums={2,1,3} target=35,我日哦,如果用大脑去解决,你得想吐了。
所以我需要想想这是为什么,首先1+1,然后+1,然后+1.。。。。。然后好多好多+1,emmmm,出来了一个35的方案了,然后下一轮首先1+1,然后+1,然后+1.。。。。。然后好多好多+1再+3。等一下前面的1+1+1什么的是不是很熟悉!我们为什么不把它记住呢!所以,dp[]来了!
dp[]数组是什么呢,它是一个长度为target+1的int数组,首先,0为1;它的意思就是默认nums数组中组合为0的可能方式设定为1.然后,dp[1]等一系列元素我们暂时设置为-1,表示还未进行计算。这样,由顶而下的动态规划就出来了,我们将求解一个巨大的target分解为求解一个较小的target,而求解这个较小的target又会被分解为求解一个更小的target。。。。。。直到最后,而在这过程中,求解出来的target我们都存储在了dp数组中!那么求解到最后,我们岂不是一直进行数组的调用就可以了!只进行了很少的计算!代码如下:
private int combinationSum4_dp(int[] nums, int target){
dp = new int[target + 1];
Arrays.fill(dp, -1);
dp[0] = 1;
return helper(nums, target);
}
private int helper(int[] nums, int target){
/**
* dp记录到达索引指示的target有几种方案去解决
* 就是相当于记住它的中间结果!!!
*/
if (dp[target] != -1) {
return dp[target];
}
int res = 0;
for (int i = 0; i < nums.length; i++) {
if (target >= nums[i]) {
res += helper(nums, target - nums[i]);
}
}
dp[target] = res;
return res;
}
是不是清晰很多,我们首先进行了较小target的组合数,然后依次往大再往大。。。。。。这样到最后我们就解决了那个看似很大的target。这不就是动态规划的思想吗!
所以以后首先要找到大问题和小问题之间共有的特性,列出一定的状态转移规律,然后设计满足条件的小问题解决方案,最后凭借记忆中的中间值快速求出最终解!
当然动态规划问题极多,有待后续继续进步。。。。。。
动态规划,以LeetCode-CombinationSumIV问题为例的更多相关文章
- 【动态规划】leetcode - Maximal Square
称号: Maximal Square Given a 2D binary matrix filled with 0's and 1's, find the largest square contain ...
- 动态规划 算法(DP)
多阶段决策过程(multistep decision process)是指这样一类特殊的活动过程,过程可以按时间顺序分解成若干个相互联系的阶段,在每一个阶段都需要做出决策,全部过程的决策是一个决策序列 ...
- [leetcode]multiply-strings java代码
题目: Given two numbers represented as strings, return multiplication of the numbers as a string. Note ...
- 【Leetcode】179. Largest Number
Given a list of non negative integers, arrange them such that they form the largest number. For exam ...
- 动态规划1——最长递增子序列、最长公共子序列、最长公共子串(python实现)
目录 1. 最长递增序列 2. 最长公共子序列 3. 最长公共子串 1. 最长递增序列 给定一个序列,找出其中最长的,严格递增的子序列的长度(不要求连续). 解法一:动态规划 通过一个辅助数组记录每一 ...
- leetcode常见算法与数据结构汇总
leetcode刷题之后,很多问题老是记忆不深刻,因此特意开此帖: 一.对做过题目的总结: 二.对一些方法精妙未能领会透彻的代码汇总,进行时常学习: 三.总结面试笔试常见题目,并讨论最优解法及各种解法 ...
- SQL排名问题,100% leetcode答案大公开!
(首先原谅我最近新番看多了,起了一个中二的名字) 最近在找实习,所以打算系统总结(复习)一下sql中经常遇到问题.不管是刷leetcode还是牛客的sql题,有一个问题总是绕不开的,那就是排名问题.其 ...
- lintcode:First Missing Positive 丢失的第一个正整数
题目 丢失的第一个正整数 给出一个无序的整数数组,找出其中没有出现的最小正整数. 样例 如果给出 [1,2,0], return 3 如果给出 [3,4,-1,1], return 2 挑战 只允许时 ...
- 【概率DP入门】
http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html 有关概率和期望问题的研究 摘要 在各类信息学竞赛中(尤其是ACM竞赛中) ...
随机推荐
- Android Animation动画实战(一): 从布局动画引入ListView滑动时,每一Item项的显示动画
前言: 之前,我已经写了两篇博文,给大家介绍了Android的基础动画是如何实现的,如果还不清楚的,可以点击查看:Android Animation动画详解(一): 补间动画 及 Android An ...
- hdu 1050 Moving Tables (Greedy)
Problem - 1050 过两天要给12的讲贪心,于是就做一下水贪心练习练习. 代码如下: #include <cstdio> #include <iostream> #i ...
- oracle 用EXISTS替换DISTINCT
当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换 例如: 低效: SELECT DISTINCT DEPT_NO, ...
- while循环计算1-100和,1-100内偶数/奇数/被整除的数的和
文章地址 https://www.cnblogs.com/sandraryan/ <!DOCTYPE html> <html lang="en"> < ...
- Python--day40--threading模块的几个方法
import time import threading #threading.get_ident() 查看当前进程号 def wahaha(n): time.sleep(0.5) print(n,t ...
- 代码片段 修改Windows用户名
cmd /c wmic useraccount where name=' 记录防备忘
- 2018-12-14-恢复-U-盘隐藏文件夹
title author date CreateTime categories 恢复 U 盘隐藏文件夹 lindexi 2018-12-14 19:24:56 +0800 2018-12-14 19: ...
- async和await的执行顺序问题
说明 : 要了解执行顺序,所需要的知识是了解浏览器js运行机制,以及微任务和宏任务的先后顺序.如果你明白了宏任务.微任务,请往下看: async function async1 () { consol ...
- ioctl 命令的实现
ioctl 的 scull 实现只传递设备的配置参数, 并且象下面这样容易: switch(cmd) { case SCULL_IOCRESET: scull_quantum = SCULL_QUAN ...
- linux 一次对一个用户限制存取
单打开设备之外的下一步是使一个用户在多个进程中打开一个设备, 但是一次只允许一个 用户打开设备. 这个解决方案使得容易测试设备, 因为用户一次可从几个进程读写, 但是 假定这个用户负责维护在多次存取中 ...