动态规划,以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竞赛中) ...
随机推荐
- Install Openjdk11 to Ubuntu 18.04 LTS
Ubuntu 18.04 LTS系统上通过sudo apt install openjdk-11-*命令安装的jdk11版本依然是jdk10,怎么样才能安装openjdk 11呢,今天,我们就来完 ...
- oracle 使用显式的游标(CURSORs)
使用隐式的游标,将会执行两次操作. 第一次检索记录, 第二次检查TOO MANY ROWS 这个exception . 而显式游标不执行第二次操作.
- 使用提示(Hints)
对于表的访问,可以使用两种Hints. FULL 和 ROWID FULL hint 告诉ORACLE使用全表扫描的方式访问指定表. 例如: SELECT /*+ FULL(EMP) */ * FRO ...
- Laravel获取所有的数据库表及结构
遇到一个需求,需要修改数据库中所有包含email的字段的表,要把里面的长度改为128位.Laravel获取所有的表,然后循环判断表里面有没有email这个字段.代码如下: use Illuminate ...
- Java如何计算hashcode值
在设计一个类的时候,很可能需要重写类的hashCode()方法,此外,在集合HashSet的使用上,我们也需要重写hashCode方法来判断集合元素是否相等. 下面给出重写hashCode()方法的基 ...
- uni-app学习记录06-Vuex简单使用
import Vue from 'vue' // 这里引入vuex import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Stor ...
- HDU 1326
题意:给出一堆高度不一的砖头,现在使他们高度一样,问最少的移动次数,(每减少1就是移动一次) 思路:求出平均高度,然后模拟最后平均高度的数组,也就是说,每个数组对应每一个平均高度,也就是说比平均高度大 ...
- python编程之进程
进程:运行中的程序 进程和操作系统的关系:进程是操作系统调度和资源分配的最小单位,是操作系统的结构基础. 那么为什么要有进程呢? 程序在运行时,会使用各种硬件资源,如果他们之间没有界限,那么程序之间的 ...
- 2019-1-29-WPF-设置输入只能英文
title author date CreateTime categories WPF 设置输入只能英文 lindexi 2019-1-29 15:8:4 +0800 2018-2-13 17:23: ...
- Ajax与PHP通信
以下是HTML的Js代码 $data = { va:$('#num').text() }; $.ajax({ type: 'POST', url: "A.php", data: $ ...