From ea4ea28e3c480997b264b038af78c105f5436aff Mon Sep 17 00:00:00 2001 From: liu13 <1099976891@qq.com> Date: Sun, 18 Aug 2019 15:42:02 +0800 Subject: [PATCH] 20190818 --- .gitignore | 3 +- code/lc1026.java | 2 +- code/lc105.java | 13 ++++++ code/lc113.java | 2 +- code/lc148.java | 4 +- code/lc149.java | 2 +- code/lc153.java | 2 +- code/lc22.java | 2 +- code/lc236.java | 6 +-- code/lc239.java | 2 +- code/lc300.java | 6 +-- code/lc315.java | 1 + code/lc324.java | 22 +--------- code/lc384.java | 2 +- code/lc395.java | 2 +- code/lc416.java | 1 + code/lc42.java | 2 +- code/lc493.java | 4 +- code/lc572.java | 9 ++-- code/lc617.java | 4 +- code/lc84.java | 6 +-- interview/bk2.java | 28 +++++++++++++ interview/bk4.java | 102 +++++++++++++++++++++++++++++++++++++++++++++ 23 files changed, 175 insertions(+), 52 deletions(-) create mode 100644 interview/bk2.java create mode 100644 interview/bk4.java diff --git a/.gitignore b/.gitignore index 79f908f..a65b6cc 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 60021b9..744124f 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 2e3f709..77f526a 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 230aa48..0099744 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 61b55e7..a2fffc8 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 db52cde..460b592 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 cc9085f..eb10a0e 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 aad3916..147e14f 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 037e49e..c1d1da1 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 8ee51c6..a46859e 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 daefa73..1bf5acc 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 1d30118..80884d2 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 ef8c4ae..c5698ce 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 a595529..c304b55 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 7d88179..bac92d2 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 20eabbe..72babb6 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 5a61b34..78e737e 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 52913b2..45bf1eb 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 645ee0c..fe16bfc 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 0000000..92a364c --- /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); + } +} -- GitLab