diff --git a/code/lc102.java b/code/lc102.java index 8d63c77f3c3a9775b2104b5485857f727b078188..dd6d9c03f26604aa3874112f8ba30a06349ca3e3 100644 --- a/code/lc102.java +++ b/code/lc102.java @@ -23,7 +23,7 @@ public class lc102 { if(root==null) return res; qu.add(root); - while(!qu.isEmpty()){ + while(!qu.isEmpty()){ //两个while int size = qu.size(); List temp = new ArrayList<>(); while(size>0){ diff --git a/code/lc113.java b/code/lc113.java index b8515e07238ee743c3f4bceef9301533d3435907..230aa48cfa4ea578c783a21f949f190f6072bab5 100644 --- a/code/lc113.java +++ b/code/lc113.java @@ -20,20 +20,20 @@ public class lc113 { } } public List> pathSum(TreeNode root, int sum) { - List> res = new ArrayList<>(); - helper(res, root, sum, 0, new ArrayList<>()); + List> res = new ArrayList(); + helper(res, new ArrayList(), root, sum); return res; } - public void helper(List> res, TreeNode root, int sum, int curr, List curr_ls) { + public void helper(List> res, List cur, TreeNode root, int sum){ if(root==null) return; - curr_ls.add(root.val); - if(curr+root.val==sum && root.left==null && root.right==null) { //到叶子节点 - res.add(new ArrayList<>(curr_ls)); - curr_ls.remove(curr_ls.size()-1); - return; + cur.add(root.val); + if(root.left==null&&root.right==null&&root.val==sum){ //到叶子节点 + res.add(new ArrayList(cur)); + }else{ + helper(res, cur, root.left, sum-root.val); + helper(res, cur, root.right, sum-root.val); } - helper(res, root.left, sum, curr+root.val, curr_ls); - helper(res, root.right, sum, curr+root.val, curr_ls); - curr_ls.remove(curr_ls.size()-1); + cur.remove(cur.size()-1); + return; } } diff --git a/code/lc123.java b/code/lc123.java index 7ff46543c34ba8a0c44c27a93ea9bf755c21ed6a..8fc5c2f7eb538660121eea5b145b852643327769 100644 --- a/code/lc123.java +++ b/code/lc123.java @@ -1,6 +1,6 @@ package code; /* - * 122. Best Time to Buy and Sell Stock III + * 123. Best Time to Buy and Sell Stock III * 题意:买卖股票最大利润,只能买卖2次 * 难度:Hard * 分类:Array, Dynamic Programming diff --git a/code/lc131.java b/code/lc131.java index 8d048e169f0f239a3a84f8adc8e9309f6f70a9e1..165b6e1c5b804e779c53660ec3a3bcfc459036d3 100644 --- a/code/lc131.java +++ b/code/lc131.java @@ -10,6 +10,7 @@ import java.util.List; * 思路:典型回溯法,注意向res添加内容时要重新new一下 * Tips: lc5, lc9, lc125, lc131, lc234, lc647 * lc39 + * lc132 * 判断是否为回文的方法: * 1. 从中心往两边扩充,中心可能是一个字符,也可能是两个字符 * 2. dp,利用之前计算的结果,只判断边缘两个字符是否相等,从后往前dp diff --git a/code/lc132.java b/code/lc132.java new file mode 100644 index 0000000000000000000000000000000000000000..c18d13065aab13f7ebe3f51181bc18ea5555e608 --- /dev/null +++ b/code/lc132.java @@ -0,0 +1,52 @@ +package code; +import java.util.Arrays; + +/* + * 132. Palindrome Partitioning II + * 题意:最少切几刀,回文串 + * 难度:Hard + * 分类:Dynamic Programming + * 思路:和lc300思路很像,只是多了判断。dp[i]表示从0到i这一段切法的最小值,每次遍历前边的结果,看能否接上。 + * 可以把判断回文和dp两个合并,因为用dp的形式判断回文 + * Tips:lc300 + * bingo! + */ + +public class lc132 { + public int minCut(String s) { + int[] dp = new int[s.length()+1]; + Arrays.fill(dp, s.length()); //fill最大值 + dp[0] = 0; + for(int i=1; i i - 1 || pal[j + 1][i - 1])) { + pal[j][i] = true; + min = j == 0 ? 0 : Math.min(min, cut[j - 1] + 1); + } + } + cut[i] = min; + } + return cut[n - 1]; + } +} diff --git a/code/lc139.java b/code/lc139.java index 67ac6a61c0adb0d377bddb46367e11561a7d6218..1d767356017c46f1b10e9f7eb8bd9af88984fe87 100644 --- a/code/lc139.java +++ b/code/lc139.java @@ -6,8 +6,10 @@ package code; * 分类:Dynamic Programming * 思路:动态规划 * Tips:巧妙的方法,防止了复杂的操作,通过遍历之前计算出来的结果 + * 递归的方法本质和dp是一样的,记住用备忘录算法,把之前的结果记下来 * lc140 */ +import java.util.HashMap; import java.util.List; public class lc139 { @@ -22,4 +24,16 @@ public class lc139 { } return dp[s.length()]; } + + HashMap hm = new HashMap(); + public boolean wordBreak2(String s, List wordDict) { + if(hm.containsKey(s)) return hm.get(s); + if(s.length() == 0) return true; + Boolean flag = false; + for(String word:wordDict){ + if(s.startsWith(word)) flag = flag||wordBreak(s.substring(word.length()), wordDict); //注意函数 startsWith + } + hm.put(s, flag); + return flag; + } } diff --git a/code/lc141.java b/code/lc141.java index 1f8bf71edf569dace8539060faa1ee5d4cc03b67..971a82c3ca838c86d09052c6ee2483db79e48eea 100644 --- a/code/lc141.java +++ b/code/lc141.java @@ -14,15 +14,13 @@ public class lc141 { ListNode(int x) { val = x; } } public boolean hasCycle(ListNode head) { - if(head==null) - return false; - ListNode faster = head; + if(head==null||head.next==null) return false; ListNode slow = head; - while( faster.next!=null && faster.next.next!=null){ //注意判断条件,slow一定不等于null,不用判断了 + ListNode fast = head.next; + while(fast!=null&&fast.next!=null){ //注意判断条件,slow一定不等于null,不用判断了 slow = slow.next; - faster = faster.next.next; - if(slow==faster) - return true; + fast = fast.next.next; + if(fast==slow) return true; } return false; } diff --git a/code/lc142.java b/code/lc142.java index 389e108065181d6b2adabb95bab41a9ec59243c2..b7b8adfc7811b17d67be27c856461df0a53af000 100644 --- a/code/lc142.java +++ b/code/lc142.java @@ -32,4 +32,23 @@ public class lc142 { } return null; } + + public ListNode detectCycle2(ListNode head) { + if(head==null||head.next==null) return null; + ListNode slow = head; + ListNode fast = head.next; + while(fast!=null&&fast.next!=null){ + slow = slow.next; + fast = fast.next.next; + if(slow==fast){ + slow = slow.next; + while(head!=slow){ + head = head.next; + slow = slow.next; + } + return slow; + } + } + return null; + } } diff --git a/code/lc148.java b/code/lc148.java index 290e85ec78c8256a9e0191a6902cdd88b3e69a98..61b55e76c397356809c792f2543d305dc7ca8f7a 100644 --- a/code/lc148.java +++ b/code/lc148.java @@ -25,7 +25,7 @@ public class lc148 { if( head==null || head.next == null ){ return head; } - ListNode slow = head; + ListNode slow = head; //记一下 ListNode fast = head.next; while( fast!=null && fast.next!=null ){ //把链表分成两半 slow = slow.next; diff --git a/code/lc207.java b/code/lc207.java index 8e7f0757a65350fac90c3da47981871499c0e3f3..7a387b072f7dd8e073cafaf200e7744314512e5a 100644 --- a/code/lc207.java +++ b/code/lc207.java @@ -23,7 +23,7 @@ public class lc207 { for (int i = 0; i < prerequisites.length ; i++) { int node1 = prerequisites[i][0]; int node2 = prerequisites[i][1]; - graph[node2][node1] = 1; + graph[node2][node1] = 1; //存下邻接矩阵,方便后续查找是否有边 indegree[node1]++; //存下入度,入度为0时,表示该课程可以修 } Stack st = new Stack(); diff --git a/code/lc226.java b/code/lc226.java index 30443bb56f88da6462866b4a9bd956f81b8e4be8..9524a5b1c20b8019cc06f629ea6ed56798c33604 100644 --- a/code/lc226.java +++ b/code/lc226.java @@ -19,8 +19,7 @@ public class lc226 { } public TreeNode invertTree(TreeNode root) { //递归 - if(root==null) - return null; + if(root==null) return null; TreeNode temp = root.left; root.left = root.right; root.right = temp; diff --git a/code/lc300.java b/code/lc300.java index 1003cf49c94e97eba2af2aee4e36946cd87173e2..daefa73054ee8c13f912bb2619137a184550bfbc 100644 --- a/code/lc300.java +++ b/code/lc300.java @@ -6,6 +6,7 @@ package code; * 分类:Binary Search, Dynamic Programming * 思路:基本的思路是dp[i]记录以nums[i]结尾的最长长度,每次遍历 dp[i] 得到dp[i+1],复杂度为O(n^2)。最优的解法是O(nlgn),dp[i]是递增的数组,每次插入时二分查找是lgn。 * Tips:经典题目,记一下 + * lc132 */ import java.util.Arrays; diff --git a/code/lc309.java b/code/lc309.java index a7d9b08cbe49eba535caaad5e206b377e0b65406..3a0ce768a934034b5b8aadce7d2e3edc283a9f0d 100644 --- a/code/lc309.java +++ b/code/lc309.java @@ -27,4 +27,18 @@ public class lc309 { } return Math.max(s,b); } + + public int maxProfit2(int[] prices) { + if(prices.length==0) return 0; + int[] sell = new int[prices.length]; + int[] buy = new int[prices.length]; + sell[0] = 0; + buy[0] = -prices[0]; + for(int i=1; i0&&nums[ptr-1]>=nums[ptr]){// 注意是 >= {5,1,1} , 等于-- ptr--; } - - if(ptr!=0){ - //从这个数之后的数中找出第一个比x大的数 - int n = nums[ptr]; - int ptr2 = ptr; - for(int i=ptr+1; inums[ptr-1] && nums[i]<=n ) {//注意 <= {2,3,1,3,3} - n = nums[i]; - ptr2 = i; - } + ptr--; + if(ptr!=-1){ + //从后往前,找比 + int val = nums[ptr]; + int ptr2 = nums.length-1; + while(ptr2>ptr){ + if(nums[ptr2]>nums[ptr]) break; + ptr2--; } - nums[ptr2] = nums[ptr-1]; - nums[ptr-1] = n; + nums[ptr] = nums[ptr2]; + nums[ptr2] = val; } //把之后的数逆序 - ReverseNums(nums,ptr,nums.length-1); + ReverseNums(nums,ptr+1,nums.length-1); //+1,不包含ptr那个位置 } public static void ReverseNums(int[] nums, int start, int end){ int l = end+start; diff --git a/code/lc32.java b/code/lc32.java index 041752ea35056bb5f64970341b96a2a9a7af0eb0..d61ed8bf3fabb43902f8f1580caf5ca421016057 100644 --- a/code/lc32.java +++ b/code/lc32.java @@ -28,7 +28,7 @@ public class lc32 { else{ if(s.charAt(i-2)=='('){ // 这种情况:(())() dp[i] = dp[i-2]+2; - }else if(i-2-dp[i-1]>=0 && s.charAt(i-2-dp[i-1])=='('){ // 这种情况:()(()) + }else if(i-2-dp[i-1]>=0 && s.charAt(i-2-dp[i-1])=='('){ // 这种情况:()(()) , 第一个判断是判断索引是否合法 dp[i] = dp[i-1] + dp[i-2-dp[i-1]]+2; } } @@ -49,7 +49,7 @@ public class lc32 { st.push(i); else if(ch==')'){ st.pop(); - if(st.isEmpty()) + if(st.isEmpty()) //截断一下 st.push(i); res = Math.max(res,i-st.peek()); } diff --git a/code/lc416.java b/code/lc416.java index a618c4020b2131e13cd7818e2c3c2bd104fd6003..a595529ed199273dfc09b33ea175049b7ab8a6cf 100644 --- a/code/lc416.java +++ b/code/lc416.java @@ -69,5 +69,21 @@ public class lc416 { return dp[volumn]; } + public boolean canPartition3(int[] nums) { + int sum = 0; + for(int i: nums) sum+=i; + if(sum%2==1) return false; + sum = sum/2; + boolean[][] dp = new boolean[nums.length+1][sum+1]; + for(int i =0; i<=nums.length; i++) dp[i][0]=true; //注意赋值0 + for(int i=1; i<=nums.length; i++){ + for(int j=1; j<=sum; j++){ + dp[i][j] = dp[i-1][j]; + if(j>=nums[i-1]) dp[i][j]= dp[i][j] || dp[i-1][j-nums[i-1]]; //注意判断index是否合法 + } + } + return dp[nums.length][sum]; + } + } diff --git a/code/lc76.java b/code/lc76.java index 6d075a0cab10818285e9fdc1ade182d03b95d03f..6b8c407f4d398566e91ce4464e02990762e04ccb 100644 --- a/code/lc76.java +++ b/code/lc76.java @@ -17,7 +17,7 @@ public class lc76 { } public static String minWindow(String s, String t) { HashMap mp = new HashMap(); - for (int i = 0; i < t.length() ; i++) { //统计每个字符出现的个数 + for (int i = 0; i < t.length() ; i++) { // 统计每个字符出现的个数 char ch = t.charAt(i); if(mp.containsKey(ch)) mp.put(ch,mp.get(ch)+1); @@ -37,7 +37,7 @@ public class lc76 { if(mp.get(ch_r)>=0) // <0说明重复了 count++; } - while(count==t.length()){//右移左指针 + while(count==t.length()){//右移左指针,注意这个判定条件 if(right-left+1 hm = new HashMap(); + char[] t_arr = t.toCharArray(); + for(int i=0; i=0) count--; //别忘了这一层的判断 + } + right++; //在if外边 + while(count==0){ //注意判断条件 + if(right-left+10) count++; + } + left++; + } + } + return s.substring(res_left, res_right); + } } diff --git a/code/lc94.java b/code/lc94.java index 1f93c8191c4a68c7f9a53656708aad0a34f75f63..1bd956e42ce997cd7bfb89fd63921564e0b6071e 100644 --- a/code/lc94.java +++ b/code/lc94.java @@ -5,7 +5,7 @@ package code; * 难度:Medium * 分类:HashTable, Stack, Tree * 思路:左节点依次入栈二叉树中序遍历 - * Tips:和lc144前序,lc145后序一起看 + * Tips:和lc144前序,lc145后序一起看, lc102层次遍历 */ import java.util.ArrayList; import java.util.List; diff --git a/code/lc978.java b/code/lc978.java index 1cdb748cf6a4d0dcc0ef65750c4067c00eef6745..35653a1b0968173a8a0c2b42a034bedba482d93f 100644 --- a/code/lc978.java +++ b/code/lc978.java @@ -28,7 +28,7 @@ public class lc978 { public int maxTurbulenceSize2(int[] A) { int[] arr = new int[A.length-1]; - for(int i=1; iA[i-1]) arr[i-1] = 1; else arr[i-1] = -1;