diff --git a/.gitignore b/.gitignore index 79f908f0afe56321322a26c10ea1c122948286ad..a65b6cc78029f18203af9a30b0902d898c51e1f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store */.DS_Store -/kickstart/* +kickstart/* test.java +interview/* diff --git a/code/lc1026.java b/code/lc1026.java index 60021b92cab838e62c7b9095946969081ddfd3ba..744124f799363ef60edce8ab778e454867484675 100644 --- a/code/lc1026.java +++ b/code/lc1026.java @@ -1,6 +1,6 @@ package code; /* - * 1025. Maximum Difference Between Node and Ancestor + * 1026. Maximum Difference Between Node and Ancestor * 题意:父节点减子节点的绝对值最大 * 难度: * 分类: diff --git a/code/lc105.java b/code/lc105.java index 2e3f709d3b35f865be1467af0ac5cb8d6082e8ed..77f526abdea9455ebec33452f071f05e43975187 100644 --- a/code/lc105.java +++ b/code/lc105.java @@ -37,4 +37,17 @@ public class lc105 { return tn; //记住函数的返回值的设置,返回Node,递归的构造子树 } + public TreeNode buildTree2(int[] preorder, int[] inorder) { + return helper(preorder, inorder, 0, 0, preorder.length-1); + } + public TreeNode helper(int[] preorder, int[] inorder, int cur, int left, int right){ + if(left>right) return null; + TreeNode tn = new TreeNode(preorder[cur]); + int i = left; + for(; i<=right; i++) if(inorder[i]==preorder[cur]) break; + tn.left = helper(preorder, inorder, cur+1, left, i-1); + tn.right = helper(preorder, inorder, cur+i-left+1, i+1, right); + return tn; + } + } diff --git a/code/lc113.java b/code/lc113.java index 230aa48cfa4ea578c783a21f949f190f6072bab5..0099744be2816a43b5f9444cf3e65f2a4d8ced14 100644 --- a/code/lc113.java +++ b/code/lc113.java @@ -33,7 +33,7 @@ public class lc113 { helper(res, cur, root.left, sum-root.val); helper(res, cur, root.right, sum-root.val); } - cur.remove(cur.size()-1); + cur.remove(cur.size()-1); //注意是去掉最后一个,传的是索引。传递对象的话,序列可能会变。 return; } } diff --git a/code/lc148.java b/code/lc148.java index 61b55e76c397356809c792f2543d305dc7ca8f7a..a2fffc8d72d4a025e61f38056490727852998796 100644 --- a/code/lc148.java +++ b/code/lc148.java @@ -75,9 +75,9 @@ public class lc148 { public ListNode partion(ListNode head, ListNode end) { ListNode p1 = head, p2 = head.next; - + //p1指的是小于pivot的索引 //走到末尾才停 - while (p2 != end) { //p1与p2间都是大于pivot的数 + while (p2 != end) { //head到p1间是小于pivot的数,p1与p2间都是大于pivot的数 if (p2.val < head.val) { //lc922 类似的思想, 把小于的值放到该放的位置上 p1 = p1.next; diff --git a/code/lc149.java b/code/lc149.java index db52cdebb98d816ad06ea8e1f2c032a453f63939..460b59236110423c47f8005123dfe36739bc2dcc 100644 --- a/code/lc149.java +++ b/code/lc149.java @@ -20,7 +20,7 @@ public class lc149 { public int maxPoints(Point[] points) { if(points.length<=2) return points.length; int res = 0; - for (int i = 0; i < points.length-1 ; i++) { + for (int i = 0; i < points.length-1 ; i++) {//先固定一个点,再根据斜率进行记录就行了 HashMap> hm = new HashMap<>(); int overlap = 1; int max = 0; diff --git a/code/lc153.java b/code/lc153.java index cc9085faa243261a3f12b8960b7edf56c853aa5c..eb10a0e71f2368229e75ee5645367874d065cd95 100644 --- a/code/lc153.java +++ b/code/lc153.java @@ -16,7 +16,7 @@ public class lc153 { int mid = (left+right)/2; if(nums[mid]nums[right]){ + }else{ left = mid+1; } } diff --git a/code/lc22.java b/code/lc22.java index aad3916b682fbd87c9b8a3842684180d8f2b6563..147e14fb1b9959e0a6a400f9f6408b76420ffb8a 100644 --- a/code/lc22.java +++ b/code/lc22.java @@ -1,7 +1,7 @@ package code; /* * 22. Generate Parentheses - * 题意:正确括号组合的 + * 题意:正确括号组合 * 难度:Medium * 分类:String, Backtracking * 思路:回溯法的典型题目,按选优条件向前搜索,达到目标后就退回一步或返回 diff --git a/code/lc236.java b/code/lc236.java index 037e49e93cbeaaea9d72184b9f2d4906b451be42..c1d1da1e7a8f25967c4f352f08a8dd01fe9566ae 100644 --- a/code/lc236.java +++ b/code/lc236.java @@ -23,10 +23,8 @@ public class lc236 { return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); - if( left!=null && right!=null ) //回溯返回。哪边不为空,返回哪边,否则返回自己。 - return root; - else if(left!=null) - return left; + if( left!=null && right!=null ) return root; //回溯返回。哪边不为空,返回哪边,否则返回自己。 + else if(left!=null) return left; else return right; } diff --git a/code/lc239.java b/code/lc239.java index 8ee51c6ef3ea5724a619f9ac8502e79f2cb949f2..a46859eda78669c0485286bc8ad84342a3303954 100644 --- a/code/lc239.java +++ b/code/lc239.java @@ -25,7 +25,7 @@ public class lc239 { return new int[]{}; int[] res = new int[nums.length-k+1]; int cur = 0; - Deque dq = new ArrayDeque(); //队列里是递减的 + Deque dq = new ArrayDeque(); //队列里是递减的,存的仍然是下标 for (int i = 0; i < nums.length ; i++) { if( !dq.isEmpty() && dq.peekFirst()<=i-k) //窗口长度过长了,删掉头 dq.removeFirst(); diff --git a/code/lc300.java b/code/lc300.java index daefa73054ee8c13f912bb2619137a184550bfbc..1bf5accde8eb8ebe8f3001dd27a0dc4dc1bdf560 100644 --- a/code/lc300.java +++ b/code/lc300.java @@ -38,10 +38,8 @@ public class lc300 { int right = size; while(left!=right){ //得到要插入的位置 int mid = (left+right)/2; - if(dp[mid]在右边 if (copy[j] < median) { - swap(copy, i++, j++); + swap(copy, j++, i++); } else if (copy[j] > median) { swap(copy, j, k--); } else { @@ -32,27 +32,13 @@ public class lc324 { for (int i = n - 1, j = 1; i >= m; i--, j += 2) nums[j] = copy[i]; } - - - private int getMiddle(int[] nums, int l, int r) { - int i = l; - - for (int j = l + 1; j <= r; j++) { - if (nums[j] < nums[l]) swap(nums, ++i, j); - } - - swap(nums, l, i); - return i; - } - private void swap(int[] nums, int i, int j) { int t = nums[i]; nums[i] = nums[j]; nums[j] = t; } - - public static int findMedium(int[] nums, int left, int right, int k){ + public int findMedium(int[] nums, int left, int right, int k){ int cur = nums[left]; int l = left; int r = right; @@ -70,8 +56,4 @@ public class lc324 { else if(left>=k) return findMedium(nums, l, right-1, k); else return findMedium(nums, right+1, r, k); } - - public static int newIndex(int index, int n) { - return (1 + 2*index) % (n | 1); - } } diff --git a/code/lc384.java b/code/lc384.java index 1d3011823989320eb150d616611759555524913e..80884d2d7dad6bece53abb21054bc473af749144 100644 --- a/code/lc384.java +++ b/code/lc384.java @@ -25,7 +25,7 @@ public class lc384 { public int[] shuffle() { int[] rand = new int[nums.length]; for (int i = 0; i < nums.length; i++){ - int r = (int) (Math.random() * (i+1)); + int r = (int) (Math.random() * (i+1)); // +1是因为下标从0开始 rand[i] = rand[r]; rand[r] = nums[i]; } diff --git a/code/lc395.java b/code/lc395.java index ef8c4ae25b41934052c81495036c2b1e7b8123f0..c5698ce4cb87eada19940608778a1b329ff4c433 100644 --- a/code/lc395.java +++ b/code/lc395.java @@ -23,7 +23,7 @@ public class lc395 { if( cur_uni_char==i && more_than_k_char==i) res = Math.max(res, right-left); - else if(cur_uni_char>i){ //左边推进。不在外边加上一个循环的话,就不知道怎么推荐左指针了。 + else if(cur_uni_char>i){ //左边推进。不在外边加上一个循环的话,就不知道怎么推进左指针了。 while(cur_uni_char!=i){ map[s.charAt(left)-'a']--; if(map[s.charAt(left)-'a']==0) cur_uni_char--; diff --git a/code/lc416.java b/code/lc416.java index a595529ed199273dfc09b33ea175049b7ab8a6cf..c304b554ded5a062d6d71034992fe2622cec5ddc 100644 --- a/code/lc416.java +++ b/code/lc416.java @@ -11,6 +11,7 @@ import java.util.HashSet; * 0,1背包问题,递推比较简单,所以空间可以压缩成一维 * 自己想的思路其实和压缩后的0,1背包类似,但没想到该问题可以抽象为0,1背包 * dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i]] + * i表示数组长度,j表示求和为j * Tips:lc416, lc494 */ public class lc416 { diff --git a/code/lc42.java b/code/lc42.java index 7d88179dc96cb5a698c95185be2ca1162a477d9a..bac92d20f80665d5020049ba677a84873f46f033 100644 --- a/code/lc42.java +++ b/code/lc42.java @@ -52,7 +52,7 @@ public class lc42 { int i = 0, maxWater = 0, maxBotWater = 0; while (i < A.length){ if (s.isEmpty() || A[i]<=A[s.peek()]){ - s.push(i++); + s.push(i++); //递减栈 } else { int bot = s.pop(); diff --git a/code/lc493.java b/code/lc493.java index 20eabbe3eb3d52059583de3d88baebde7e9c8110..72babb6c769dbd62b80fe99d5c0bde955d73b69e 100644 --- a/code/lc493.java +++ b/code/lc493.java @@ -6,11 +6,11 @@ import java.util.Arrays; * 493. Reverse Pairs * 题意:逆序对 * 难度:Hard - * 分类: + * 分类:Binary Search, Divide and Conquer, Sort, Binary Indexed Tree, Segment Tree * 思路:归并排序的思路 或者 树相关的数据结构 * 排序前先count * 负数怎么解决? 不用考虑,因为排序前先count - * Tips: + * Tips:lc315 */ public class lc493 { public static void main(String[] args) { diff --git a/code/lc572.java b/code/lc572.java index 5a61b34fbeed24e7bf792970b336fc90eabbd015..78e737ee4299de878d1eae16ff22972a03f8684e 100644 --- a/code/lc572.java +++ b/code/lc572.java @@ -19,13 +19,12 @@ public class lc572 { } public boolean isSubtree(TreeNode s, TreeNode t) { - if (s == null) return false; - return helper(s,t) || isSubtree(s.left,t) ||isSubtree(s.right,t); // 注意递归方法的不同,是调用哪个函数 + if( s==null || t==null ) return s==t; + return helper(s,t) || isSubtree(s.left, t) || isSubtree(s.right, t); // 注意递归方法的不同,是调用哪个函数 } public boolean helper(TreeNode s, TreeNode t){ - if( s==null && t==null ) return true; - if( s==null || t==null || s.val!=t.val ) return false; - return helper(s.left, t.left) && helper(s.right, t.right); + if( s==null || t==null ) return s==t; + return s.val==t.val && helper(s.left, t.left) && helper(s.right, t.right); } public boolean isSubtree2(TreeNode s, TreeNode t) { diff --git a/code/lc617.java b/code/lc617.java index 52913b22d2cacd9f1dd55dd3fc629c61a92a2e4b..45bf1eb6b8355e0d51ebe101cd3f5c854831a66a 100644 --- a/code/lc617.java +++ b/code/lc617.java @@ -44,8 +44,8 @@ public class lc617 { public TreeNode mergeTrees2(TreeNode t1, TreeNode t2) { if(t1==null) return t2; //这里注意一下,比较难想明白,可以记一下 if(t2==null) return t1; - t1.left = mergeTrees(t1.left, t2.left); - t1.right = mergeTrees(t1.right, t2.right); + t1.left = mergeTrees(t1.left, t2.left); //搞定下层指针 + t1.right = mergeTrees(t1.right, t2.right); //前边判断过了,两个都不为null t1.val += t2.val; return t1; } diff --git a/code/lc84.java b/code/lc84.java index 645ee0c22d2f7b641c348b1f7a68cb2cb9cda9be..fe16bfcd684d17fa93d4b8eadb43ebeaaf8ffa9a 100644 --- a/code/lc84.java +++ b/code/lc84.java @@ -27,14 +27,14 @@ public class lc84 { if( st.size()==0 || h>heights[st.peek()] ){ //递增入栈,保证栈内索引对应的Height递增 st.push(i); }else{ - int n = st.pop(); + int n = st.pop(); //计算该位置height高度的矩形 int left; if(st.isEmpty()) left = -1; //若为空,则到最左边 else left = st.peek(); - res = Math.max(res, heights[n] * (i-left-1)); //i之前的,要-1 - i--; + res = Math.max(res, heights[n] * (i-left-1)); //i之前的,要-1; 注意是height[n], 不是height[i] + i--; //注意i--,相当于循环出栈,总体复杂度还是O(n),因为栈最大是heights.len } } return res; diff --git a/interview/bk2.java b/interview/bk2.java new file mode 100644 index 0000000000000000000000000000000000000000..92a364c3fe41823da5f0ec5db4f80400aaba8b19 --- /dev/null +++ b/interview/bk2.java @@ -0,0 +1,28 @@ +package interview; + +public class bk2 { + public static void main(String[] args) { + + } + + public int lengthOfLIS2(int[] nums) { + if(nums.length<2) + return nums.length; + int size = 0; //size指dp中递增的长度。 dp[0~i] 表示了长度为 i+1 的递增子数组,且最后一个值是最小值 + int[] dp = new int[nums.length]; //dp存储递增的数组,之后更新这个数组。如果x>最后一个值,则插入到末尾,否则更新对应位置上的值为该值。 + for (int i = 0; i < nums.length ; i++) { + int left = 0; + int right = size; + while(left!=right){ //得到要插入的位置 + int mid = (left+right)/2; + if(dp[mid]0?arr[j-1]:0); + cur += Math.max(max1 - arr[j]+1, 0); + } + max1 = Math.max(max1, j>0?arr[j-1]:0); + int max2 = -1; + j = arr.length-1; + for (; j>i ; j--) { + max2 = Math.max(max2+1, j= 0 ; j --) { + if(nums[j] <= nums[j + 1]) { + sum += nums[j + 1] + 1 - nums[j]; + nums[j] = nums[j + 1] + 1; + } + } + if(sum < count) + count = sum; + for(int i = 0; i < n; i ++) { + nums[i] = temp[i]; + } + for(int i = 1; i < n - 1; i ++) { + sum = 0; + int j = 1; + for(; j < i; j ++) { + if(nums[j] <= nums[j - 1]) { + sum += nums[j - 1] + 1 - nums[j]; + nums[j] = nums[j - 1] + 1; + } + } + j --; + int k = n - 2; + for(; k > i; k--) { + if(nums[k] <= nums[k + 1]) { + sum += nums[k + 1] + 1 - nums[k]; + nums[k] = nums[k + 1] + 1; + } + } + k ++; + int res = Math.max(nums[j], nums[k]); + if(nums[i] <= res) { + sum += res + 1 - nums[i]; + } + if(sum < count) + count = sum; + for(int l = 0; l < n; l ++) { + nums[l] = temp[l]; + } + } + System.out.println(count); + } +}