LeetCode---Backtracking && DP
**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的更多相关文章
- leetcode distinct-subsequences(DP)
参考https://oj.leetcode.com/problems/distinct-subsequences 动态规划方程 dp[i][j]=dp[i-1][j-1]+dp[i-1][j] (s( ...
- [LeetCode] Backtracking Template for (Subsets, Permutations, and Combination Sum)
根据issac3 用Java总结了backtracking template, 我用他的方法改成了Python. 以下为template. def backtrack(ans, temp, nums, ...
- [Leetcode] Backtracking回溯法解题思路
碎碎念: 最近终于开始刷middle的题了,对于我这个小渣渣确实有点难度,经常一两个小时写出一道题来.在开始写的几道题中,发现大神在discuss中用到回溯法(Backtracking)的概率明显增大 ...
- [Leetcode][Python][DP]Regular Expression Matching
# -*- coding: utf8 -*-'''https://oj.leetcode.com/problems/regular-expression-matching/ Implement reg ...
- leetcode HouseRobber Dp Code
#include <malloc.h> int MAX(int x,int y){ return x>y?x:y;} int rob(int* nums, int numsSize) ...
- Leetcode:【DP】Longest Palindromic Substring 解题报告
Longest Palindromic Substring -- HARD 级别 Question SolutionGiven a string S, find the longest palindr ...
- leetcode 76 dp& 强连通分量&并查集经典操作
800. Similar RGB Color class Solution { int getn(int k){ return (k+8)/17; } string strd(int k){ char ...
- LeetCode: Palindrome 回文相关题目
LeetCode: Palindrome 回文相关题目汇总 LeetCode: Palindrome Partitioning 解题报告 LeetCode: Palindrome Partitioni ...
- [LintCode]——目录
Yet Another Source Code for LintCode Current Status : 232AC / 289ALL in Language C++, Up to date (20 ...
- Java Algorithm Problems
Java Algorithm Problems 程序员的一天 从开始这个Github已经有将近两年时间, 很高兴这个repo可以帮到有需要的人. 我一直认为, 知识本身是无价的, 因此每逢闲暇, 我就 ...
随机推荐
- JS基础_流程控制语句
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- JS基础_逻辑运算符
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Typora入门:全网最全教程
目录 简介 Markdown介绍 常用快捷键 块元素 换行符 标题级别 引用文字 无序列表 有序列表 任务列表 代码块 数学表达式 插入表格 脚注 分割线 目录(TOC) 跨度元素 链接 网址 图片 ...
- 12 Django之Cookie和Session
一.什么是Cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接 ...
- react——使用this.setState({ })修改state状态值
使用this.setState({ }) 还可以修改后追加传的参数 效果如下: this.setState({ })方法是异步的
- 开源you-get项目爬虫,以及基于python+selenium的自动测试利器
写在前面 爬虫和自动测试,对于python来说是最合适不过也是最擅长的. 开源的项目也很多,例如you-get项目https://github.com/soimort/you-get.盗链和爬虫神器. ...
- 深入学习Mybatis框架(一)- 入门
1.什么是Mybatis? Mybatis是一个优秀持久层框架,提供了对数据库的一系列操作(增删改查).Mybatis可以避免重复的写JDBC代码,让我们以较少的代码实现对数据库的操作,从而提高开发效 ...
- Visual Studio 添加 自定义 路径宏
在编辑VS工程包含路径和库路径时,有时需要添加第三方包的路径,比如c++ boost库, 为了协作的方便,不合适直接把本地绝对路径添加入工程设置,此时可以添加自定义路径宏, 然后参与协作的每个开发人员 ...
- 以tomcat镜像为基础部署war包后再做成镜像
#以交互的方式启动本地的镜像tomcat:hps,并且将本地目录/mnt/iso挂在到容器中的/tmp/repositories目录,方便从本地获取一些安装文件并进行一些操作 docker run - ...
- c++ 一些注意事项
1.long int的字节信息:int在32位系统下是4字节,long在32位也是4字节,在64位Int不变,但是long变成8字节,所以我们的编译器不同可能会导致我们处理int,long不同 2.注 ...