leecode更新
This commit is contained in:
parent
e948057876
commit
c9c55164b7
|
|
@ -17,7 +17,7 @@ import java.util.List;
|
|||
* 对于给定的输入,保证和为 target 的不同组合数少于 150 个。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class combinationSum {
|
||||
public class T04_CombinationSum {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
|
@ -15,7 +15,7 @@ import java.util.*;
|
|||
* 注意:解集不能包含重复的组合。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class combinationSum2 {
|
||||
public class T05_CombinationSum2 {
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
|
|
@ -15,7 +15,7 @@ import java.util.List;
|
|||
* 回文串 是正着读和反着读都一样的字符串。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class partition {
|
||||
public class T06_Partition {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
|
@ -17,7 +17,7 @@ import java.util.List;
|
|||
* 给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class RestoreIpAddresses {
|
||||
public class T07_RestoreIpAddresses {
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package com.markilue.leecode.backtrace.second;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.backtrace.second
|
||||
*@Author: dingjiawen
|
||||
*@CreateTime: 2023-02-01 09:53
|
||||
*@Description:
|
||||
* TODO 二刷力扣39题 组合总和:
|
||||
* 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
|
||||
* candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
|
||||
* 对于给定的输入,保证和为 target 的不同组合数少于 150 个。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T04_CombinationSum {
|
||||
|
||||
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
List<Integer> cur = new ArrayList<>();
|
||||
|
||||
public List<List<Integer>> combinationSum(int[] candidates, int target) {
|
||||
Arrays.sort(candidates);
|
||||
backtracking(candidates,target,0,0);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public void backtracking(int[] candidates, int target, int sum,int now) {
|
||||
if (sum == target) {
|
||||
result.add(new ArrayList<>(cur));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = now; i < candidates.length; i++) {
|
||||
if (sum + candidates[i] > target) {//剪枝
|
||||
return;
|
||||
}
|
||||
cur.add(candidates[i]);
|
||||
backtracking(candidates, target, sum + candidates[i],i);
|
||||
cur.remove(cur.size()-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方最快,form记录一个数最多能用多少次,小于0就不能用了
|
||||
* @param con
|
||||
* @param target
|
||||
* @param form
|
||||
* @param cur
|
||||
* @param sum
|
||||
* @param start
|
||||
*/
|
||||
private void deal(List<List<Integer>> con,int target,int[] form,List<Integer> cur,int sum,int start){
|
||||
//dfs
|
||||
if(sum==target) {
|
||||
con.add(new ArrayList<Integer>(cur));
|
||||
return;
|
||||
}
|
||||
for(int i=start;i<=target-sum;++i){
|
||||
if(form[i]>0){
|
||||
cur.add(i);
|
||||
--form[i];
|
||||
sum+=i;
|
||||
deal(con,target,form,cur,sum,i);
|
||||
sum-=i;
|
||||
++form[i];
|
||||
cur.remove(cur.size()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
|
||||
int[] form=new int[51];
|
||||
for(int i=0;i<candidates.length;++i){
|
||||
++form[candidates[i]];
|
||||
}
|
||||
List<List<Integer>> con=new ArrayList<List<Integer>>();
|
||||
deal(con,target,form,new ArrayList<Integer>(),0,1);
|
||||
return con;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.markilue.leecode.backtrace.second;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.backtrace.second
|
||||
*@Author: dingjiawen
|
||||
*@CreateTime: 2023-02-01 10:22
|
||||
*@Description:
|
||||
* TODO 二刷力扣40题 组合总和II:
|
||||
* 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
|
||||
* candidates 中的每个数字在每个组合中只能使用 一次 。
|
||||
* 注意:解集不能包含重复的组合。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T05_CombinationSum2 {
|
||||
|
||||
List<Integer> cur=new ArrayList<>();
|
||||
List<List<Integer>> result=new ArrayList<>();
|
||||
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
|
||||
Arrays.sort(candidates);
|
||||
backtracking(candidates,target,0,0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void backtracking(int[] candidates, int target,int sum ,int startIndex) {
|
||||
if(target==sum){
|
||||
result.add(new ArrayList<>(cur));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = startIndex; i < candidates.length; i++) {
|
||||
if(sum+candidates[i]>target){
|
||||
return;
|
||||
}
|
||||
if(i!=startIndex&&candidates[i]==candidates[i-1])continue;
|
||||
cur.add(candidates[i]);
|
||||
backtracking(candidates,target,sum+candidates[i],i+1);
|
||||
cur.remove(cur.size()-1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
package com.markilue.leecode.backtrace.second;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.backtrace.second
|
||||
*@Author: dingjiawen
|
||||
*@CreateTime: 2023-02-01 11:01
|
||||
*@Description:
|
||||
* TODO 二刷力扣131题 分割回文串:
|
||||
* 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
|
||||
* 回文串 是正着读和反着读都一样的字符串。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T06_Partition {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String s = "abbab";
|
||||
|
||||
System.out.println(partition(s));
|
||||
}
|
||||
|
||||
List<List<String>> result = new ArrayList<>();
|
||||
List<String> cur = new ArrayList<>();
|
||||
boolean[][] flag;
|
||||
|
||||
public List<List<String>> partition(String s) {
|
||||
flag = new boolean[s.length()][s.length()];
|
||||
computePalindrome1(s);
|
||||
backtracking(s.toCharArray(), 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用动态规划前:速度击败73.84%,内存击败55.32% 7ms
|
||||
* 使用动态规划后:速度击败99.22%,内存击败47.98% 6ms
|
||||
* @param chars
|
||||
* @param start
|
||||
*/
|
||||
public void backtracking(char[] chars, int start) {
|
||||
if (start == chars.length) {
|
||||
//分完了,直接加入
|
||||
result.add(new ArrayList<>(cur));
|
||||
return;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = start; i < chars.length; i++) {
|
||||
builder.append(chars[i]);
|
||||
if (flag[start][i]) {
|
||||
cur.add(builder.toString());
|
||||
backtracking(chars, i + 1);
|
||||
cur.remove(cur.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isPalindrome(char[] chars, int start, int end) {
|
||||
if (start == end) {
|
||||
return true;
|
||||
}
|
||||
while (start < end) {
|
||||
if (chars[start++] != chars[end--]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 事实上判断回文不需要一个一个进行判断,可以通过动态规划递归进行判断
|
||||
* TODO 动态规划五部曲:
|
||||
* 1)dp定义:dp[i][j]表示start为i,end为j的字符串是否是回文
|
||||
* 2)dp状态转移方程:dp[i][j]可以通过dp[i+1][j-1]来推断
|
||||
* dp[i][j]=char[i]==char[j]&&dp[i+1][j-1]
|
||||
* 3)dp遍历顺序:由于需要知道i+1,j-1所以需要从下到上,左到右
|
||||
* 4)dp初始化:dp[i][i]=true;dp[i][i>j]=true
|
||||
* 5)dp距离推导: s="aab"
|
||||
* [a a b]
|
||||
* i=0: t t f
|
||||
* i=1: t t f
|
||||
* i=2: t t t
|
||||
*
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
public void computePalindrome(String s) {
|
||||
char[] chars = s.toCharArray();
|
||||
//初始化,下三角全为true
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
for (int j = 0; j <= i; j++) {
|
||||
flag[i][j] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = s.length() - 2; i >= 0; i--) {
|
||||
for (int j = s.length() - 1; j > i; j--) {
|
||||
flag[i][j] = chars[i] == chars[j] && flag[i + 1][j - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据官方的优化
|
||||
* @param s
|
||||
*/
|
||||
public void computePalindrome1(String s) {
|
||||
char[] chars = s.toCharArray();
|
||||
// //初始化,下三角全为true
|
||||
// for (int i = 0; i < s.length(); i++) {
|
||||
// for (int j = 0; j <= i; j++) {
|
||||
// flag[i][j] = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
for (int i = s.length() - 1; i >= 0; i--) {
|
||||
for (int j = i; j <s.length(); j++) {
|
||||
if(i==j) flag[i][j]=true;
|
||||
else if(j==i+1) flag[i][j]=chars[i]==chars[j];//相差1的时候只需要判断这两个数是否相等
|
||||
else flag[i][j] = chars[i] == chars[j] && flag[i + 1][j - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据一维dp优化
|
||||
* @param s
|
||||
*/
|
||||
public void computePalindrome2(String s) {
|
||||
char[] chars = s.toCharArray();
|
||||
// //初始化,下三角全为true
|
||||
// for (int i = 0; i < s.length(); i++) {
|
||||
// for (int j = 0; j <= i; j++) {
|
||||
// flag[i][j] = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
for (int i = s.length() - 1; i >= 0; i--) {
|
||||
for (int j = i; j <s.length(); j++) {
|
||||
if(i==j) flag[i][j]=true;
|
||||
else if(j==i+1) flag[i][j]=chars[i]==chars[j];//相差1的时候只需要判断这两个数是否相等
|
||||
else flag[i][j] = chars[i] == chars[j] && flag[i + 1][j - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
package com.markilue.leecode.backtrace.second;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.backtrace.second
|
||||
*@Author: dingjiawen
|
||||
*@CreateTime: 2023-02-01 12:36
|
||||
*@Description:
|
||||
* TODO 二刷力扣93题 复原IP地址:
|
||||
* 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。
|
||||
* 例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。
|
||||
* 给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T07_RestoreIpAddresses {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String s = "25525511135";
|
||||
String s1 = "0000";
|
||||
System.out.println(restoreIpAddresses(s1));
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 本质上类似于切割回文T06,核心在于最后一层一定要切完
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public List<String> restoreIpAddresses(String s) {
|
||||
backtracking(s, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void backtracking(String s, int level, int start) {
|
||||
if (level == 4) {
|
||||
builder.deleteCharAt(builder.length() - 1);
|
||||
result.add(builder.toString());
|
||||
builder.append(".");
|
||||
return;
|
||||
}
|
||||
int flag = start + 3 > s.length() ? s.length() : start + 3;
|
||||
for (int i = start; i < flag; i++) {
|
||||
String now;
|
||||
if (level == 3) {
|
||||
now = s.substring(i);
|
||||
if (!isFit(now)) return;
|
||||
} else {
|
||||
now = s.substring(start, i + 1);
|
||||
}
|
||||
if (isFit(now)) {
|
||||
builder.append(now).append(".");
|
||||
backtracking(s, level + 1, i + 1);
|
||||
int last = builder.length();
|
||||
builder.delete(last - now.length() - 1, last);
|
||||
}
|
||||
if (level == 3) {
|
||||
//最后一层就一次
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isFit(String s) {
|
||||
if (s.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (s.length() > 1 && s.charAt(0) == '0') {
|
||||
return false;
|
||||
}
|
||||
long num = Long.parseLong(s);
|
||||
|
||||
return num >= 0 && num <= 255;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方最快0ms
|
||||
* 使用segment记录pasInt的数,最后在拼接,避免了一系列删除增加“.”的操作
|
||||
*/
|
||||
List<String> res = new ArrayList<>();
|
||||
int[] segment = new int[4];
|
||||
public List<String> restoreIpAddresses1(String s) {
|
||||
dfs(s,0,0);
|
||||
return res;
|
||||
}
|
||||
public void dfs(String s,int segnum,int p){
|
||||
if(segnum == 4){
|
||||
if(p == s.length()){
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int i = 0;i < 4;i++){
|
||||
sb.append(segment[i]);
|
||||
if(i != 3){
|
||||
sb.append('.');
|
||||
}
|
||||
}
|
||||
res.add(sb.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(p == s.length()){
|
||||
return;
|
||||
}
|
||||
if(s.charAt(p) == '0'){
|
||||
segment[segnum] = 0;
|
||||
dfs(s,segnum+1,p+1);
|
||||
}
|
||||
int sum = 0;
|
||||
for(int i = p;i < s.length();i++){
|
||||
sum = sum * 10 + s.charAt(i) - '0';
|
||||
if(sum > 0 && sum <= 255){
|
||||
segment[segnum] = sum;
|
||||
dfs(s,segnum+1,i+1);
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue