From 87dc8f81b47dbc0a7805a4a7964f70e7134dbe9c Mon Sep 17 00:00:00 2001 From: liu13 <1099976891@qq.com> Date: Mon, 1 Jul 2019 11:04:03 +0800 Subject: [PATCH] 20190701 --- code/lc1027.java | 2 +- code/lc114.java | 2 +- code/lc125.java | 2 +- code/lc127.java | 2 +- code/lc131.java | 7 ++++++- code/lc218.java | 2 +- code/lc22.java | 1 + code/lc227.java | 2 +- code/lc234.java | 1 + code/lc237.java | 11 +++-------- code/lc239.java | 2 +- code/lc240.java | 2 +- code/lc279.java | 2 +- code/lc297.java | 2 +- code/lc3.java | 1 + code/lc301.java | 1 + code/lc309.java | 5 +++-- code/lc315.java | 2 +- code/lc32.java | 1 + code/lc322.java | 15 +++++++++++++++ code/lc334.java | 2 +- code/lc378.java | 2 +- code/lc5.java | 1 + code/lc647.java | 2 +- code/lc9.java | 2 +- 25 files changed, 48 insertions(+), 26 deletions(-) diff --git a/code/lc1027.java b/code/lc1027.java index 5404934..224d302 100644 --- a/code/lc1027.java +++ b/code/lc1027.java @@ -14,7 +14,7 @@ public class lc1027 { int[][] dp = new int[A.length][20000]; for (int i = 0; i < A.length ; i++) { for (int j = 0; j < i ; j++) { - int ind = A[i]-A[j]+10000; + int ind = A[i]-A[j]+10000; //可能是负数,做一个偏移 dp[i][ind] = dp[j][ind] + 1; res = Math.max(res, dp[i][ind]); } diff --git a/code/lc114.java b/code/lc114.java index 86def24..78c544f 100644 --- a/code/lc114.java +++ b/code/lc114.java @@ -5,7 +5,7 @@ package code; * 难度:Medium * 分类:Tree, Depth-first Search * 思路:就是节点间连接换一下,理清思路就行了,类似中序遍历 - * Tips: + * Tips:lc426 */ public class lc114 { public class TreeNode { diff --git a/code/lc125.java b/code/lc125.java index 6d87ab6..fecc88d 100644 --- a/code/lc125.java +++ b/code/lc125.java @@ -6,7 +6,7 @@ package code; * 分类:Two Pointers, String * 思路:两个指针。另一种是正则表达式替换数字,字母为空格,再反转,判断是否相等。 * Tips:记下另一种方法。第一种方法Bingo! - * lc234, lc5 + * lc5, lc9, lc125, lc131, lc234, lc647 */ public class lc125 { public static void main(String[] args) { diff --git a/code/lc127.java b/code/lc127.java index 4d0d365..ee44bb6 100644 --- a/code/lc127.java +++ b/code/lc127.java @@ -29,7 +29,7 @@ public class lc127 { curr_str[j] = k; if(String.valueOf(curr_str).equals(endWord)) return level; if(wordList.contains(String.valueOf(curr_str))){ - wordList.remove(String.valueOf(curr_str)); + wordList.remove(String.valueOf(curr_str)); //这要remove qu.add(String.valueOf(curr_str)); } } diff --git a/code/lc131.java b/code/lc131.java index 2d1d1b6..8d048e1 100644 --- a/code/lc131.java +++ b/code/lc131.java @@ -8,7 +8,12 @@ import java.util.List; * 难度:Medium * 分类:Backtracking * 思路:典型回溯法,注意向res添加内容时要重新new一下 - * Tips:lc39 + * Tips: lc5, lc9, lc125, lc131, lc234, lc647 + * lc39 + * 判断是否为回文的方法: + * 1. 从中心往两边扩充,中心可能是一个字符,也可能是两个字符 + * 2. dp,利用之前计算的结果,只判断边缘两个字符是否相等,从后往前dp + * 3. 翻转了以后,判断两个串是否相等 */ public class lc131 { public static void main(String[] args) { diff --git a/code/lc218.java b/code/lc218.java index 021387b..4da9dfb 100644 --- a/code/lc218.java +++ b/code/lc218.java @@ -39,7 +39,7 @@ public class lc218 { int pre = 0; for (int i = 0; i < arr.length ; i++) { if(arr[i][1]>0){ - pr.add(-arr[i][1]); + pr.add(-arr[i][1]); //默认是最小优先队列 }else{ pr.remove(arr[i][1]); } diff --git a/code/lc22.java b/code/lc22.java index bbeb2e2..aad3916 100644 --- a/code/lc22.java +++ b/code/lc22.java @@ -6,6 +6,7 @@ package code; * 分类:String, Backtracking * 思路:回溯法的典型题目,按选优条件向前搜索,达到目标后就退回一步或返回 * 注意:递归法别忘了两块的拼接,例如n=4时,可以由2,2拼起来作为答案 + * lc32, lc22, lc301 */ import java.util.ArrayList; import java.util.HashSet; diff --git a/code/lc227.java b/code/lc227.java index 693b296..2e6e633 100644 --- a/code/lc227.java +++ b/code/lc227.java @@ -21,7 +21,7 @@ public class lc227 { if(Character.isDigit(chs[i])){ num = num * 10 + chs[i]-'0'; } - if( !Character.isDigit(chs[i]) || i==chs.length-1 ){ //便利到最后,即使不是符号,也要计算 + if( !Character.isDigit(chs[i]) || i==chs.length-1 ){ //遍历到最后,即使不是符号,也要计算 if(sign=='+'){ st.push(num); } diff --git a/code/lc234.java b/code/lc234.java index 012f87e..4af8a27 100644 --- a/code/lc234.java +++ b/code/lc234.java @@ -6,6 +6,7 @@ package code; * 分类:LinkedList, Two Pointers * 思路:反转一半就行了,避免了空间开销 * Tips:很好的题,考了 Two Pointers, 还考了链表反转 + * lc5, lc9, lc125, lc131, lc234, lc647 */ public class lc234 { public class ListNode { diff --git a/code/lc237.java b/code/lc237.java index 6523055..ef1da09 100644 --- a/code/lc237.java +++ b/code/lc237.java @@ -4,7 +4,7 @@ package code; * 题意:删除链表中的一个节点,给的是这个节点,不知道前边的节点 * 难度:Easy * 分类:Linked List - * 思路:剑指Offer上有,拷贝下一个节点的内容到该节点,倒数第二个节点置空 + * 思路:剑指Offer上有,拷贝下一个节点的内容到该节点,删除下一个节点 * Tips: */ public class lc237 { @@ -17,12 +17,7 @@ public class lc237 { } } public void deleteNode(ListNode node) { - ListNode pre = new ListNode(-1); - while(node.next!=null) { - node.val = node.next.val; - pre = node; - node = node.next; - } - pre.next = null; + node.val = node.next.val; + node.next = node.next.next; } } diff --git a/code/lc239.java b/code/lc239.java index 3044d85..8ee51c6 100644 --- a/code/lc239.java +++ b/code/lc239.java @@ -27,7 +27,7 @@ public class lc239 { int cur = 0; Deque dq = new ArrayDeque(); //队列里是递减的 for (int i = 0; i < nums.length ; i++) { - if( !dq.isEmpty() && dq.peekFirst()<=i-k) + if( !dq.isEmpty() && dq.peekFirst()<=i-k) //窗口长度过长了,删掉头 dq.removeFirst(); while( !dq.isEmpty() && nums[dq.peekLast()]<=nums[i]){// removeLast 不是 First。 自己写的时候这写错了,如果是First的话,有些Case也能过 dq.removeLast(); diff --git a/code/lc240.java b/code/lc240.java index 0514993..fd578e3 100644 --- a/code/lc240.java +++ b/code/lc240.java @@ -5,7 +5,7 @@ package code; * 难度:Medium * 分类:Binary Search, Divide and Conquer * 思路:两种方法,一种O(mlg(n)),遍历每一行,每行二分查找。另一种O(m+n),从右上角开始移动 - * Tips: + * Tips:lc240, lc378 */ public class lc240 { public boolean searchMatrix(int[][] matrix, int target) { diff --git a/code/lc279.java b/code/lc279.java index 32ac5a6..eaaa99d 100644 --- a/code/lc279.java +++ b/code/lc279.java @@ -5,7 +5,7 @@ package code; * 难度:Medium * 分类:Math, Dynamic Programming, Breadth-first Search * 思路:dp[i] = dp[i-j*j] +1 - * Tips: + * Tips:lc322 */ import java.util.Arrays; diff --git a/code/lc297.java b/code/lc297.java index d6749ef..5f3b70f 100644 --- a/code/lc297.java +++ b/code/lc297.java @@ -42,7 +42,7 @@ public class lc297 { // Decodes your encoded data to tree. public TreeNode deserialize(String data) { Deque nodes = new LinkedList<>(); - nodes.addAll(Arrays.asList(data.split(spliter))); + nodes.addAll(Arrays.asList(data.split(spliter))); //split return buildTree(nodes); } diff --git a/code/lc3.java b/code/lc3.java index 1b56f97..c3ece44 100644 --- a/code/lc3.java +++ b/code/lc3.java @@ -5,6 +5,7 @@ package code; * 难度:Medium * 分类:Hash Table, Two Pointers, String * 算法:两个指针,记录没有重复字母的子串的首和尾 +* lc76 */ import java.util.HashMap; diff --git a/code/lc301.java b/code/lc301.java index 8d2fc76..919056f 100644 --- a/code/lc301.java +++ b/code/lc301.java @@ -6,6 +6,7 @@ package code; * 分类:Depth-first Search, Breadth-first Search * 思路:先计数),如果多的话,在前边的字符里删掉一个。反转字符串,计数( * Tips:好难啊,里边很多细节需要注意。还有一种bfs的思路,挨个删字符,判断是否合规。 + * lc32, lc22, lc301 */ import java.util.ArrayList; import java.util.HashSet; diff --git a/code/lc309.java b/code/lc309.java index 907ddda..a7d9b08 100644 --- a/code/lc309.java +++ b/code/lc309.java @@ -5,16 +5,17 @@ package code; * 难度:Medium * 分类:Dynamic Programming * 思路:状态DP,自己不会写。要分两种状态,手中有股票时最大收益,手中没股票时最大收益(包括冷冻期)。 + * buy[i] means before day i what is the maxProfit for any sequence end with buy. * buy[i] = max( buy[i-1], sell[i-2]-price[i] ) * sell[i] = max( sell[i-1], buy[i-1]+price[i] ) - * 空间压缩以后时间是O(n),空间是O(1) + * 压缩以后时间是O(n),空间是O(1) * Tips:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75931/Easiest-JAVA-solution-with-explanations * lc121, lc309, lc188, lc123, lc714 */ public class lc309 { public int maxProfit(int[] prices) { if(prices.length==0) return 0; - int b1 = -prices[0]; + int b1 = -prices[0]; //注意这里的初始化 int s2=0, s1=0; int b = 0, s = 0; for (int i = 0; i < prices.length ; i++) { diff --git a/code/lc315.java b/code/lc315.java index 61defc0..6a5223d 100644 --- a/code/lc315.java +++ b/code/lc315.java @@ -9,7 +9,7 @@ import java.util.List; * 难度:Hard * 分类:Divide and Conquer, Binary indexed Tree, Segment Tree, Binary Search Tree * 思路:两种思路,一种用二叉搜索树这类数据结构 https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76580/9ms-short-Java-BST-solution-get-answer-when-building-BST - * 一种归并排序的思路,归并的时候统计左右交换数目。如果一个数从这个数的右边交换到左边,则+1。因为有重复数字,所以用将ndex进行排序 + * 一种归并排序的思路,归并的时候统计左右交换数目。如果一个数从这个数的右边交换到左边,则+1。因为有重复数字,所以用将index进行排序 * https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76583/11ms-JAVA-solution-using-merge-sort-with-explanation * 再有一种复杂度稍微高点的思路,从后往前插入排序,插入的时候二分搜索 * https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76576/My-simple-AC-Java-Binary-Search-code diff --git a/code/lc32.java b/code/lc32.java index 4d611d8..041752e 100644 --- a/code/lc32.java +++ b/code/lc32.java @@ -9,6 +9,7 @@ import java.util.Stack; * 分类:Dynamic Programming, String * 思路:两种常规方法,一是dp,每个位置记录以该位置结尾的最长长度。另一种是用栈,把位置索引入栈。 * Tips:想到了用dp,也想到了用数组记录位置结尾的解,但没有想好如何进行更新迭代计算。把位置索引入栈的方法很典型,关注一下。 + * lc32, lc22, lc301 */ public class lc32 { public static void main(String[] args) { diff --git a/code/lc322.java b/code/lc322.java index f771b81..986c2ea 100644 --- a/code/lc322.java +++ b/code/lc322.java @@ -35,4 +35,19 @@ public class lc322 { } return dp[amount-1]==Integer.MAX_VALUE ? -1 : dp[amount-1]; //没解返回-1 } + + public static int coinChange2(int[] coins, int amount) { + int max = amount + 1; + int[] dp = new int[amount + 1]; + Arrays.fill(dp, max); + dp[0] = 0; + for (int i = 1; i <= amount; i++) { + for (int j = 0; j < coins.length; j++) { + if (coins[j] <= i) { + dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1); + } + } + } + return dp[amount] > amount ? -1 : dp[amount]; + } } diff --git a/code/lc334.java b/code/lc334.java index a02b941..864d102 100644 --- a/code/lc334.java +++ b/code/lc334.java @@ -4,7 +4,7 @@ package code; * 题意:数组中是否存在递增的3个数 * 难度:Medium * 分类:Array - * 思路:思路很清奇,自己没想到,时间空间复杂度都是O(1)。其实和lc300 O(nlgn) 解法思路是一样的,只是固定了dp数组长度为两个数。 + * 思路:思路很清奇,自己没想到,时间复杂度O(N),空间是O(1)。其实和lc300 O(nlgn) 解法思路是一样的,只是固定了dp数组长度为两个数。 * Tips:lc300最长递增子序列 */ public class lc334 { diff --git a/code/lc378.java b/code/lc378.java index 07076ef..c82c242 100644 --- a/code/lc378.java +++ b/code/lc378.java @@ -11,7 +11,7 @@ import java.util.PriorityQueue; * 思路:两种思路。 1是类似多个有序链表合并的思路,优先队列。 * 2是二分,二分的是val,看比这个val小的数是不是k * Tips:lc23方法很像 - * lc240 + * lc240, lc378 */ public class lc378 { class Cell{ diff --git a/code/lc5.java b/code/lc5.java index e7534a2..250a156 100644 --- a/code/lc5.java +++ b/code/lc5.java @@ -6,6 +6,7 @@ package code; * 分类:String, Dynamic Programming * Tips:从后往前遍历,保证后续dp时,子情况已计算出 * 还有一种思路是从中间往两边扩展,中间有两种情况,一种一个字符,一种两个字符 + * lc5, lc9, lc125, lc131, lc234, lc647 */ public class lc5 { public static void main(String[] args) { diff --git a/code/lc647.java b/code/lc647.java index adb3b0a..d0e5dd1 100644 --- a/code/lc647.java +++ b/code/lc647.java @@ -5,7 +5,7 @@ package code; * 难度:Medium * 分类:String, Dynamic Programming * 思路:时间为N^2,用二维dp空间复杂度是N^2. 该题直接让判断是否回文,直接选择找中心字符,向两边拓展,空间为O(1) - * Tips: + * Tips:lc5, lc9, lc125, lc131, lc234, lc647 */ public class lc647 { public static void main(String[] args) { diff --git a/code/lc9.java b/code/lc9.java index cac0fd9..0f010f9 100644 --- a/code/lc9.java +++ b/code/lc9.java @@ -5,7 +5,7 @@ package code; * 难度:Easy * 分类:Math * 思路:不转换字符串的思路就是把数字反转了以后,比较是否相等 - * Tips: + * Tips:lc5, lc9, lc125, lc131, lc234, lc647 */ public class lc9 { public boolean isPalindrome(int x) { -- GitLab