Skip to content

Commit 4ca0257

Browse files
committed
20190715
1 parent abfdac6 commit 4ca0257

19 files changed

+193
-46
lines changed

code/lc102.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public List<List<Integer>> levelOrder(TreeNode root) {
2323
if(root==null)
2424
return res;
2525
qu.add(root);
26-
while(!qu.isEmpty()){
26+
while(!qu.isEmpty()){ //两个while
2727
int size = qu.size();
2828
List<Integer> temp = new ArrayList<>();
2929
while(size>0){

code/lc113.java

+11-11
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ public class TreeNode {
2020
}
2121
}
2222
public List<List<Integer>> pathSum(TreeNode root, int sum) {
23-
List<List<Integer>> res = new ArrayList<>();
24-
helper(res, root, sum, 0, new ArrayList<>());
23+
List<List<Integer>> res = new ArrayList();
24+
helper(res, new ArrayList(), root, sum);
2525
return res;
2626
}
27-
public void helper(List<List<Integer>> res, TreeNode root, int sum, int curr, List<Integer> curr_ls) {
27+
public void helper(List<List<Integer>> res, List<Integer> cur, TreeNode root, int sum){
2828
if(root==null) return;
29-
curr_ls.add(root.val);
30-
if(curr+root.val==sum && root.left==null && root.right==null) { //到叶子节点
31-
res.add(new ArrayList<>(curr_ls));
32-
curr_ls.remove(curr_ls.size()-1);
33-
return;
29+
cur.add(root.val);
30+
if(root.left==null&&root.right==null&&root.val==sum){ //到叶子节点
31+
res.add(new ArrayList(cur));
32+
}else{
33+
helper(res, cur, root.left, sum-root.val);
34+
helper(res, cur, root.right, sum-root.val);
3435
}
35-
helper(res, root.left, sum, curr+root.val, curr_ls);
36-
helper(res, root.right, sum, curr+root.val, curr_ls);
37-
curr_ls.remove(curr_ls.size()-1);
36+
cur.remove(cur.size()-1);
37+
return;
3838
}
3939
}

code/lc123.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package code;
22
/*
3-
* 122. Best Time to Buy and Sell Stock III
3+
* 123. Best Time to Buy and Sell Stock III
44
* 题意:买卖股票最大利润,只能买卖2次
55
* 难度:Hard
66
* 分类:Array, Dynamic Programming

code/lc131.java

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* 思路:典型回溯法,注意向res添加内容时要重新new一下
1111
* Tips: lc5, lc9, lc125, lc131, lc234, lc647
1212
* lc39
13+
* lc132
1314
* 判断是否为回文的方法:
1415
* 1. 从中心往两边扩充,中心可能是一个字符,也可能是两个字符
1516
* 2. dp,利用之前计算的结果,只判断边缘两个字符是否相等,从后往前dp

code/lc132.java

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package code;
2+
import java.util.Arrays;
3+
4+
/*
5+
* 132. Palindrome Partitioning II
6+
* 题意:最少切几刀,回文串
7+
* 难度:Hard
8+
* 分类:Dynamic Programming
9+
* 思路:和lc300思路很像,只是多了判断。dp[i]表示从0到i这一段切法的最小值,每次遍历前边的结果,看能否接上。
10+
* 可以把判断回文和dp两个合并,因为用dp的形式判断回文
11+
* Tips:lc300
12+
* bingo!
13+
*/
14+
15+
public class lc132 {
16+
public int minCut(String s) {
17+
int[] dp = new int[s.length()+1];
18+
Arrays.fill(dp, s.length()); //fill最大值
19+
dp[0] = 0;
20+
for(int i=1; i<dp.length; i++){
21+
for(int j=0; j<=i; j++){ //注意<=
22+
if(dp[j]!=s.length() && isPalindrome(s.substring(j,i)))
23+
dp[i] = Math.min(dp[i], dp[j]+1);
24+
}
25+
}
26+
return dp[s.length()]-1; //要-1 最后一刀是在末尾
27+
}
28+
29+
public Boolean isPalindrome(String str){
30+
if(new StringBuilder(str).reverse().toString().equals(str)) return true; //reverse一下
31+
else return false;
32+
}
33+
34+
public int minCut2(String s) {
35+
char[] c = s.toCharArray();
36+
int n = c.length;
37+
int[] cut = new int[n];
38+
boolean[][] pal = new boolean[n][n];
39+
40+
for(int i = 0; i < n; i++) {
41+
int min = i;
42+
for(int j = 0; j <= i; j++) {
43+
if(c[j] == c[i] && (j + 1 > i - 1 || pal[j + 1][i - 1])) {
44+
pal[j][i] = true;
45+
min = j == 0 ? 0 : Math.min(min, cut[j - 1] + 1);
46+
}
47+
}
48+
cut[i] = min;
49+
}
50+
return cut[n - 1];
51+
}
52+
}

code/lc139.java

+14
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
* 分类:Dynamic Programming
77
* 思路:动态规划
88
* Tips:巧妙的方法,防止了复杂的操作,通过遍历之前计算出来的结果
9+
* 递归的方法本质和dp是一样的,记住用备忘录算法,把之前的结果记下来
910
* lc140
1011
*/
12+
import java.util.HashMap;
1113
import java.util.List;
1214

1315
public class lc139 {
@@ -22,4 +24,16 @@ public boolean wordBreak(String s, List<String> wordDict) {
2224
}
2325
return dp[s.length()];
2426
}
27+
28+
HashMap<String, Boolean> hm = new HashMap();
29+
public boolean wordBreak2(String s, List<String> wordDict) {
30+
if(hm.containsKey(s)) return hm.get(s);
31+
if(s.length() == 0) return true;
32+
Boolean flag = false;
33+
for(String word:wordDict){
34+
if(s.startsWith(word)) flag = flag||wordBreak(s.substring(word.length()), wordDict); //注意函数 startsWith
35+
}
36+
hm.put(s, flag);
37+
return flag;
38+
}
2539
}

code/lc141.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@ public class ListNode {
1414
ListNode(int x) { val = x; }
1515
}
1616
public boolean hasCycle(ListNode head) {
17-
if(head==null)
18-
return false;
19-
ListNode faster = head;
17+
if(head==null||head.next==null) return false;
2018
ListNode slow = head;
21-
while( faster.next!=null && faster.next.next!=null){ //注意判断条件,slow一定不等于null,不用判断了
19+
ListNode fast = head.next;
20+
while(fast!=null&&fast.next!=null){ //注意判断条件,slow一定不等于null,不用判断了
2221
slow = slow.next;
23-
faster = faster.next.next;
24-
if(slow==faster)
25-
return true;
22+
fast = fast.next.next;
23+
if(fast==slow) return true;
2624
}
2725
return false;
2826
}

code/lc142.java

+19
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,23 @@ public ListNode detectCycle(ListNode head) {
3232
}
3333
return null;
3434
}
35+
36+
public ListNode detectCycle2(ListNode head) {
37+
if(head==null||head.next==null) return null;
38+
ListNode slow = head;
39+
ListNode fast = head.next;
40+
while(fast!=null&&fast.next!=null){
41+
slow = slow.next;
42+
fast = fast.next.next;
43+
if(slow==fast){
44+
slow = slow.next;
45+
while(head!=slow){
46+
head = head.next;
47+
slow = slow.next;
48+
}
49+
return slow;
50+
}
51+
}
52+
return null;
53+
}
3554
}

code/lc148.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public ListNode sortList(ListNode head) {
2525
if( head==null || head.next == null ){
2626
return head;
2727
}
28-
ListNode slow = head;
28+
ListNode slow = head; //记一下
2929
ListNode fast = head.next;
3030
while( fast!=null && fast.next!=null ){ //把链表分成两半
3131
slow = slow.next;

code/lc207.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public static boolean canFinish(int numCourses, int[][] prerequisites) {
2323
for (int i = 0; i < prerequisites.length ; i++) {
2424
int node1 = prerequisites[i][0];
2525
int node2 = prerequisites[i][1];
26-
graph[node2][node1] = 1;
26+
graph[node2][node1] = 1; //存下邻接矩阵,方便后续查找是否有边
2727
indegree[node1]++; //存下入度,入度为0时,表示该课程可以修
2828
}
2929
Stack<Integer> st = new Stack();

code/lc226.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ public class TreeNode {
1919
}
2020
public TreeNode invertTree(TreeNode root) {
2121
//递归
22-
if(root==null)
23-
return null;
22+
if(root==null) return null;
2423
TreeNode temp = root.left;
2524
root.left = root.right;
2625
root.right = temp;

code/lc300.java

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* 分类:Binary Search, Dynamic Programming
77
* 思路:基本的思路是dp[i]记录以nums[i]结尾的最长长度,每次遍历 dp[i] 得到dp[i+1],复杂度为O(n^2)。最优的解法是O(nlgn),dp[i]是递增的数组,每次插入时二分查找是lgn。
88
* Tips:经典题目,记一下
9+
* lc132
910
*/
1011
import java.util.Arrays;
1112

code/lc309.java

+14
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,18 @@ public int maxProfit(int[] prices) {
2727
}
2828
return Math.max(s,b);
2929
}
30+
31+
public int maxProfit2(int[] prices) {
32+
if(prices.length==0) return 0;
33+
int[] sell = new int[prices.length];
34+
int[] buy = new int[prices.length];
35+
sell[0] = 0;
36+
buy[0] = -prices[0];
37+
for(int i=1; i<prices.length; i++){
38+
sell[i] = Math.max(sell[i-1], buy[i-1]+prices[i]);
39+
if(i==1) buy[i] = Math.max(buy[i-1], 0-prices[i]);
40+
else buy[i] = Math.max(buy[i-1], sell[i-2]-prices[i]);
41+
}
42+
return Math.max(sell[prices.length-1],buy[prices.length-1]);
43+
}
3044
}

code/lc31.java

+14-16
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
* 题意:找出排列组合的下一个排列
55
* 难度:Medium
66
* 分类:Array
7-
* 思路:从后往前找第一个变小的数x,从这个数之后的数中找出第一个比x大的数,交换,再把之后的数逆序即可
7+
* 思路:从后往前找第一个变小的数x,从后往前找出比第一个x大的数,交换,再把之后的数逆序即可
88
* Tips:很典型的排列组合题,思路方法记忆一下。注意比较时是否有=。
99
*/
1010
public class lc31 {
1111
public static void main(String[] args) {
12-
int[] nums = {2,3,1,3,3};
12+
int[] nums = {1,2,3};
1313
nextPermutation(nums);
1414
for (int i:nums){
1515
System.out.println(i);
@@ -19,27 +19,25 @@ public static void main(String[] args) {
1919
public static void nextPermutation(int[] nums) {
2020
int ptr = nums.length-1;
2121

22-
//从后往前找第一个变小的数x
22+
//从后往前找第一个变小的数x 从后往前找出比第一个x大的数
2323
while(ptr>0&&nums[ptr-1]>=nums[ptr]){// 注意是 >= {5,1,1} , 等于--
2424
ptr--;
2525
}
26-
27-
if(ptr!=0){
28-
//从这个数之后的数中找出第一个比x大的数
29-
int n = nums[ptr];
30-
int ptr2 = ptr;
31-
for(int i=ptr+1; i<nums.length; i++){ //这不用这么麻烦,后边的数有序的,这可以简化
32-
if( nums[i]>nums[ptr-1] && nums[i]<=n ) {//注意 <= {2,3,1,3,3}
33-
n = nums[i];
34-
ptr2 = i;
35-
}
26+
ptr--;
27+
if(ptr!=-1){
28+
//从后往前,找比
29+
int val = nums[ptr];
30+
int ptr2 = nums.length-1;
31+
while(ptr2>ptr){
32+
if(nums[ptr2]>nums[ptr]) break;
33+
ptr2--;
3634
}
37-
nums[ptr2] = nums[ptr-1];
38-
nums[ptr-1] = n;
35+
nums[ptr] = nums[ptr2];
36+
nums[ptr2] = val;
3937
}
4038

4139
//把之后的数逆序
42-
ReverseNums(nums,ptr,nums.length-1);
40+
ReverseNums(nums,ptr+1,nums.length-1); //+1,不包含ptr那个位置
4341
}
4442
public static void ReverseNums(int[] nums, int start, int end){
4543
int l = end+start;

code/lc32.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static int longestValidParentheses(String s) {
2828
else{
2929
if(s.charAt(i-2)=='('){ // 这种情况:(())()
3030
dp[i] = dp[i-2]+2;
31-
}else if(i-2-dp[i-1]>=0 && s.charAt(i-2-dp[i-1])=='('){ // 这种情况:()(())
31+
}else if(i-2-dp[i-1]>=0 && s.charAt(i-2-dp[i-1])=='('){ // 这种情况:()(()) , 第一个判断是判断索引是否合法
3232
dp[i] = dp[i-1] + dp[i-2-dp[i-1]]+2;
3333
}
3434
}
@@ -49,7 +49,7 @@ public static int longestValidParentheses2(String s) {
4949
st.push(i);
5050
else if(ch==')'){
5151
st.pop();
52-
if(st.isEmpty())
52+
if(st.isEmpty()) //截断一下
5353
st.push(i);
5454
res = Math.max(res,i-st.peek());
5555
}

code/lc416.java

+16
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,21 @@ public boolean canPartition2(int[] nums) {
6969
return dp[volumn];
7070
}
7171

72+
public boolean canPartition3(int[] nums) {
73+
int sum = 0;
74+
for(int i: nums) sum+=i;
75+
if(sum%2==1) return false;
76+
sum = sum/2;
77+
boolean[][] dp = new boolean[nums.length+1][sum+1];
78+
for(int i =0; i<=nums.length; i++) dp[i][0]=true; //注意赋值0
79+
for(int i=1; i<=nums.length; i++){
80+
for(int j=1; j<=sum; j++){
81+
dp[i][j] = dp[i-1][j];
82+
if(j>=nums[i-1]) dp[i][j]= dp[i][j] || dp[i-1][j-nums[i-1]]; //注意判断index是否合法
83+
}
84+
}
85+
return dp[nums.length][sum];
86+
}
87+
7288

7389
}

code/lc76.java

+37-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static void main(String[] args) {
1717
}
1818
public static String minWindow(String s, String t) {
1919
HashMap<Character,Integer> mp = new HashMap();
20-
for (int i = 0; i < t.length() ; i++) { //统计每个字符出现的个数
20+
for (int i = 0; i < t.length() ; i++) { // 统计每个字符出现的个数
2121
char ch = t.charAt(i);
2222
if(mp.containsKey(ch))
2323
mp.put(ch,mp.get(ch)+1);
@@ -37,7 +37,7 @@ public static String minWindow(String s, String t) {
3737
if(mp.get(ch_r)>=0) // <0说明重复了
3838
count++;
3939
}
40-
while(count==t.length()){//右移左指针
40+
while(count==t.length()){//右移左指针,注意这个判定条件
4141
if(right-left+1<res_len){ //更新结果
4242
res_left = left;
4343
res_len = right-left+1;
@@ -56,4 +56,39 @@ public static String minWindow(String s, String t) {
5656
return "";
5757
return s.substring(res_left,res_left+res_len);
5858
}
59+
60+
public String minWindow2(String s, String t) {
61+
HashMap<Character, Integer> hm = new HashMap();
62+
char[] t_arr = t.toCharArray();
63+
for(int i=0; i<t_arr.length; i++){
64+
hm.put(t_arr[i], hm.getOrDefault(t_arr[i], 0)+1);
65+
}
66+
int left = 0;
67+
int right = 0;
68+
int count = t.length();
69+
char[] s_arr = s.toCharArray();
70+
int res = Integer.MAX_VALUE;
71+
int res_left = 0;
72+
int res_right = 0;
73+
while(right<s.length()){ //一共两个while
74+
if(hm.containsKey(s_arr[right])){
75+
hm.put(s_arr[right], hm.get(s_arr[right])-1);
76+
if(hm.get(s_arr[right])>=0) count--; //别忘了这一层的判断
77+
}
78+
right++; //在if外边
79+
while(count==0){ //注意判断条件
80+
if(right-left+1<res){ //记录结果
81+
res = right-left+1;
82+
res_left = left;
83+
res_right = right;
84+
}
85+
if(hm.containsKey(s_arr[left])){
86+
hm.put(s_arr[left], hm.get(s_arr[left])+1);
87+
if(hm.get(s_arr[left])>0) count++;
88+
}
89+
left++;
90+
}
91+
}
92+
return s.substring(res_left, res_right);
93+
}
5994
}

code/lc94.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* 难度:Medium
66
* 分类:HashTable, Stack, Tree
77
* 思路:左节点依次入栈二叉树中序遍历
8-
* Tips:和lc144前序,lc145后序一起看
8+
* Tips:和lc144前序,lc145后序一起看, lc102层次遍历
99
*/
1010
import java.util.ArrayList;
1111
import java.util.List;

0 commit comments

Comments
 (0)