**322. Coin Change
思路:动态规划,构造一个数组,存入当前index最少需要多少个coin

public int coinChange(int[] coins, int amount) {
if(coins == null || coins.length == 0 || amount <= 0) return 0;
//表示Index需要多少个coin
int[] dp = new int[amount + 1];
for(int i = 1; i < amount + 1; i++){
dp[i] = Integer.MAX_VALUE;
for(int j = 0; j < coins.length; j++){
if(coins[j] <= i && dp[i - coins[j]] != Integer.MAX_VALUE){
dp[i] = Math.min(dp[i],dp[i - coins[j]] + 1);
}
}
}
return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
}
377. Combination Sum IV
思路:构造一个数组,存入当前index能有几种组成方式

public int combinationSum4(int[] nums, int target) {
if(nums == null || nums.length == 0) return 0;
int[] dp= new int[target + 1];
dp[0] = 1;
for(int i = 1; i < target + 1; i++){
for(int j = 0; j < nums.length; j++){
//数组中提供了什么,就将小于target元素的组成种数加起来即可
if(i >= nums[j]) dp[i] += dp[i - nums[j]];
}
}
return dp[target];
}
51. N-Queens
思路:回溯,构造一个二维数组存solution,同时也判断每一次放Queen是否满足要求

public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new ArrayList<List<String>>();
char[][] ans = new char[n][n];
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
ans[i][j] = '.';
}
}
getResult(res,ans,0);
return res;
} public void getResult(List<List<String>> res,char[][] ans,int k){
int n = ans.length;
if(k == n){
res.add(construct(ans));
return;
} //k表示列,根据每一列进行搜索,因此列肯定不相同,因此下面不用判断列
for(int i = 0; i < n; i++){
if(isValid(i,k,ans)){
ans[i][k] = 'Q';
getResult(res,ans,k + 1);
ans[i][k] = '.';
}
}
} public boolean isValid(int x,int y,char[][] ans){
for(int i = 0; i < ans.length; i++){
for(int j = 0; j < ans[0].length; j++){
if(ans[i][j] == 'Q' && (x - i == y - j || x - i == j - y || x == i)){
return false;
}
}
}
return true;
} public List<String> construct(char[][] ans){
List<String> res = new ArrayList<String>();
for(int i = 0; i < ans.length; i++){
String s = new String(ans[i]);
res.add(s);
}
return res;
}
**131. Palindrome Partitioning
思路:回溯,每趟从start开始,判断若是Palindrome则存入,不是则继续循环

public List<List<String>> partition(String s) {
List<List<String>> res = new ArrayList<List<String>>();
List<String> ans = new ArrayList<String>();
getResult(res,ans,s,0);
return res;
} public void getResult(List<List<String>> res,List<String> ans,String s,int start){
if(start == s.length()){
res.add(new ArrayList<String>(ans));
return;
} for(int i = start; i < s.length(); i++){
if(isPalindrome(s,start,i)){
ans.add(s.substring(start,i + 1));
getResult(res,ans,s,i + 1);
ans.remove(ans.size() - 1);
}
}
} public boolean isPalindrome(String s,int low,int high){
while(low <= high){
if(s.charAt(low) != s.charAt(high)){
return false;
}
low++;
high--;
}
return true;
}
**416. Partition Equal Subset Sum
思路:首先根据数学关系可以判断sum一定是偶数,然后判断有没有子集之和等于sum / 2

public boolean canPartition(int[] nums) {
if(nums == null || nums.length == 0) return true;
int sum = 0;
for(int i : nums){
sum += i;
}
if(sum % 2 != 0) return false;
sum /= 2; //dp[i]表示i是否是数组子集和,若dp[j - nums[i]]是,那么dp[j]一定是
boolean[] dp = new boolean[sum + 1];
dp[0] = true;
for(int i = 0; i < nums.length; i++){
for(int j = sum; j >= nums[i]; j--){
dp[j] = dp[j] || dp[j - nums[i]];
}
}
return dp[sum];
}
**494. Target Sum
思路:根据数学关系:若将正数组合和负数组合分别表示为P和N,则P - N = S => P - N + P + N = S + P + N => 2*P = S + sum,转化为有多少个数组子集为P,即同题416

public int findTargetSumWays(int[] nums, int S) {
//若将正数组合和负数组合分别表示为P和N,则P - N = S => P - N + P + N = S + P + N => 2*P = S + sum,转化为有多少个数组子集为P
if(nums == null || nums.length == 0) return 0;
int sum = 0;
for(int i : nums){
sum += i;
}
return sum < S || (S + sum) % 2 != 0 ? 0 : dfs(nums,(S + sum) / 2);
} public int dfs(int[] nums,int target){
int[] dp = new int[target + 1];
dp[0] = 1;
for(int i = 0; i < nums.length; i++){
for(int j = target; j >= nums[i]; j--){
dp[j] += dp[j - nums[i]];
}
}
return dp[target];
}
139. Word Break
思路:动态规划,构造数组表示从当前分割之前的字符串在dict里是否存在

public boolean wordBreak(String s, List<String> wordDict) {
boolean[] dp = new boolean[s.length() + 1];
dp[0] = true; for(int i = 1; i < s.length() + 1; i++){
for(int j = 0; j < i; j++){
if(dp[j] && wordDict.contains(s.substring(j,i))){
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}
总结
70. Climbing Stairs:动态规划,形成一个斐波那契数列,用递归会超时
77. Combinations:回溯,每趟从头开始循环
357. Count Numbers with Unique Digits:数学规律:一位为10个,两位为9*9个,三位为9*9*8个...
198. House Robber:动态规划,递归方程式:dp[i] = Math.max(nums[i] + dp[i - 2],dp[i - 1]);
343. Integer Break:数学规律:4=2*2 5<2*3...则一定按2或3来分,而6=2+2+2=3+3 3*3>2*2*2,因此按3分直到num小于4
52. N-Queens II:同N-Queens,设置一个全局变量,每次符合则加一,注意不能是static,否则每次运行都会将前面运行过的结果算进去
46. Permutations:回溯,每趟从头开始,需要判断有没有重复
60. Permutation Sequence:同Permutations,只不过会超时,需要用数学手段通过k来判断字符的具体顺序
303. Range Sum Query - Immutable:动态规划:递归方程式为dp[i] = dp[i - 1] + nums[i]
304. Range Sum Query 2D - Immutable:动态规划,先算边界,再算中间
训练
413. Arithmetic Slices:由于等差数列要求必须连续,则每次计算以当前元素结尾的等差数列有几个(比上一次多1),如果不连续则重置,将所有结果相加
213. House Robber II:方法和House Robber一样,只是要分两次求最大值,因为第一家和最后一家不能同时偷,两次调用函数时注意挪位问题
368. Largest Divisible Subset:构造一个数组dp存入当前num结尾时的序列长度,然后取得最大长度的Index,同时判断整除关系和dp[index]是否符合条件依次获得序列的每个元素
47. Permutations II:同Permutations,只是要去重
**467. Unique Substrings in Wraparound String:动态规划,同413,每次计算以当前字符结尾的连续数列有几个(比上一次多1),如果不连续则重置,将所有结果相加
提示
1.字符运算成整形->'c' - 'a' = 2  整形运算成字符 (char)('0' + 1) = '1'
2.判断字符串中是否含有字符:s.indexOf(char),不能用s.contains()->参数为charSequence

LeetCode---Backtracking && DP的更多相关文章

  1. leetcode distinct-subsequences(DP)

    参考https://oj.leetcode.com/problems/distinct-subsequences 动态规划方程 dp[i][j]=dp[i-1][j-1]+dp[i-1][j] (s( ...

  2. [LeetCode] Backtracking Template for (Subsets, Permutations, and Combination Sum)

    根据issac3 用Java总结了backtracking template, 我用他的方法改成了Python. 以下为template. def backtrack(ans, temp, nums, ...

  3. [Leetcode] Backtracking回溯法解题思路

    碎碎念: 最近终于开始刷middle的题了,对于我这个小渣渣确实有点难度,经常一两个小时写出一道题来.在开始写的几道题中,发现大神在discuss中用到回溯法(Backtracking)的概率明显增大 ...

  4. [Leetcode][Python][DP]Regular Expression Matching

    # -*- coding: utf8 -*-'''https://oj.leetcode.com/problems/regular-expression-matching/ Implement reg ...

  5. leetcode HouseRobber Dp Code

    #include <malloc.h> int MAX(int x,int y){ return x>y?x:y;} int rob(int* nums, int numsSize) ...

  6. Leetcode:【DP】Longest Palindromic Substring 解题报告

    Longest Palindromic Substring -- HARD 级别 Question SolutionGiven a string S, find the longest palindr ...

  7. leetcode 76 dp& 强连通分量&并查集经典操作

    800. Similar RGB Color class Solution { int getn(int k){ return (k+8)/17; } string strd(int k){ char ...

  8. LeetCode: Palindrome 回文相关题目

    LeetCode: Palindrome 回文相关题目汇总 LeetCode: Palindrome Partitioning 解题报告 LeetCode: Palindrome Partitioni ...

  9. [LintCode]——目录

    Yet Another Source Code for LintCode Current Status : 232AC / 289ALL in Language C++, Up to date (20 ...

  10. Java Algorithm Problems

    Java Algorithm Problems 程序员的一天 从开始这个Github已经有将近两年时间, 很高兴这个repo可以帮到有需要的人. 我一直认为, 知识本身是无价的, 因此每逢闲暇, 我就 ...

随机推荐

  1. nodes.js详细安装

    nodes.js详细安装 Node.js 本章节我们将向大家介绍在window和Linux上安装Node.js的方法. 本安装教程以Node.js v4.4.3 LTS(长期支持版本)版本为例. No ...

  2. JS基础_for循环练习1

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. O059、Backup Volume 操作

    参考https://www.cnblogs.com/CloudMan6/p/5662236.html   BackUp是将Volume备份到别的地方(备份设备),将来可以通过restore操作恢复. ...

  4. js获取图片信息

    网络图片: fetch(item.path).then(function(res){ // 计算图片大小 return res.blob() }).then(function(data){ conso ...

  5. JavaScript中with不推荐使用,为什么总是出现在面试题中?

    with的基本使用 尴尬的with关键字 一.with的基本使用 with是用来扩展语句作用域的,什么意思呢?先来看看语法和示例: 语法: with(expression){ statement } ...

  6. 可能是全网最全的http面试答案

    HTTP有哪些方法? HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法 HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNE ...

  7. java基础3(异常)

    1.异常的体系 1)请描述异常的继承体系 异常继承体系为:异常的根类是 java.lang.Throwable,其下有两个子类:java.lang.Error 与 java.util.Exceptio ...

  8. java字符常量

    在Java程序中经常会遇到类似于"Hello"这样地字符串,那么这种类型的字符串是Java中是如何存储,下面就说明字符串常量在内存中存储方式: Java程序在编译时会将程序中出现的 ...

  9. JavaWeb【过滤器】

    定义: 服务器端组件,可以截取用户端的请求和响应,并对这些信息做过滤. 课程概要: 1.工作原理 2.生命周期 1.web.xml配置 注意:url-pattern配置路径前面需要加"/&q ...

  10. java中有个很强大的工具jconsole.exe

    这个工具可以监控java程序的线程,cpu和内存使用情况.