diff --git a/MCA算法突击课/第03期/mca_04/Code01_CompleteTreeNodeNumber.java b/MCA算法突击课/第03期/mca_04/Code01_CompleteTreeNodeNumber.java index 3068efc..d0e1440 100644 --- a/MCA算法突击课/第03期/mca_04/Code01_CompleteTreeNodeNumber.java +++ b/MCA算法突击课/第03期/mca_04/Code01_CompleteTreeNodeNumber.java @@ -16,6 +16,7 @@ public class Code01_CompleteTreeNodeNumber { } // 提交如下的方法 + // head为头的树一定是完全二叉树,保证这一点! public static int countNodes(TreeNode head) { if (head == null) { return 0; @@ -23,22 +24,26 @@ public class Code01_CompleteTreeNodeNumber { return bs(head, 1, mostLeftLevel(head, 1)); } - // 当前来到node节点,node节点在level层,总层数是h - // 返回node为头的子树(必是完全二叉树),有多少个节点 + // node : 当前来到的树的头部,当前这棵树一定是完全二叉树! + // Level : 在整棵大树中,node在第几层 + // h : 在整棵大树中,一共有几层 + // 返回 : 以node为头的完全二叉树有几个节点 + // 时间复杂度O((logN)的平方) ,远好于,都遍历一遍所有的节点 public static int bs(TreeNode node, int Level, int h) { if (Level == h) { return 1; } if (mostLeftLevel(node.right, Level + 1) == h) { + // (1 << (h - Level)) 就代表 : 2的(h-level)次方 return (1 << (h - Level)) + bs(node.right, Level + 1, h); } else { return (1 << (h - Level - 1)) + bs(node.left, Level + 1, h); } } - // 如果node在第level层, - // 求以node为头的子树,最大深度是多少 - // node为头的子树,一定是完全二叉树 + // node,此时在level层 + // 请顺着node的left指针,往下扎 + // 返回最终的深度 public static int mostLeftLevel(TreeNode node, int level) { while (node != null) { level++; diff --git a/MCA算法突击课/第03期/mca_04/Code02_DiameterOfBinaryTree.java b/MCA算法突击课/第03期/mca_04/Code02_DiameterOfBinaryTree.java index db812d5..04aed6c 100644 --- a/MCA算法突击课/第03期/mca_04/Code02_DiameterOfBinaryTree.java +++ b/MCA算法突击课/第03期/mca_04/Code02_DiameterOfBinaryTree.java @@ -30,6 +30,7 @@ public class Code02_DiameterOfBinaryTree { maxDistance = m; height = h; } + } public static Info process(TreeNode x) { @@ -39,9 +40,10 @@ public class Code02_DiameterOfBinaryTree { Info leftInfo = process(x.left); Info rightInfo = process(x.right); int height = Math.max(leftInfo.height, rightInfo.height) + 1; - int p1 = Math.max(leftInfo.maxDistance, rightInfo.maxDistance); - int p2 = leftInfo.height + rightInfo.height; - int maxDistance = Math.max(p1, p2); + // 可能性1&2 : 左树上的最大距离 右树上的最大距离 取最大值 + int maxDistance = Math.max(leftInfo.maxDistance, rightInfo.maxDistance); + // 可能性3 : 左高 + 右高 + maxDistance = Math.max(maxDistance, leftInfo.height + rightInfo.height); return new Info(maxDistance, height); } diff --git a/MCA算法突击课/第03期/mca_04/Code06_LIS.java b/MCA算法突击课/第03期/mca_04/Code03_LIS.java similarity index 52% rename from MCA算法突击课/第03期/mca_04/Code06_LIS.java rename to MCA算法突击课/第03期/mca_04/Code03_LIS.java index cfdcdc0..db3587b 100644 --- a/MCA算法突击课/第03期/mca_04/Code06_LIS.java +++ b/MCA算法突击课/第03期/mca_04/Code03_LIS.java @@ -1,16 +1,39 @@ package 第03期.mca_04; // 本题测试链接 : https://leetcode.cn/problems/longest-increasing-subsequence -public class Code06_LIS { +public class Code03_LIS { + + public static int common(int[] arr) { + int n = arr.length; + int[] dp = new int[n]; + // ...arr[0] + dp[0] = 1; + int maxLen = 1; + for (int i = 1; i < n; i++) { + int preLen = 0; + for (int j = 0; j < i; j++) { + if (arr[j] < arr[i]) { + preLen = Math.max(preLen, dp[j]); + } + } + dp[i] = preLen + 1; + maxLen = Math.max(maxLen, dp[i]); + } + return maxLen; + } public static int lengthOfLIS(int[] arr) { if (arr == null || arr.length == 0) { return 0; } int[] ends = new int[arr.length]; + // ends[i] : 所有长度为i+1的递增子序列,最小结尾! + // 0.....n-1 + // 0 1... ends[0] = arr[0]; - int right = 0; int max = 1; + // ends填到了哪 + int right = 0; for (int i = 1; i < arr.length; i++) { int l = 0; int r = right; @@ -22,8 +45,9 @@ public class Code06_LIS { r = m - 1; } } - right = Math.max(right, l); + // l : 就是返回的下标 ends[l] = arr[i]; + right = Math.max(right, l); max = Math.max(max, l + 1); } return max; diff --git a/MCA算法突击课/第03期/mca_04/Code04_EnvelopesProblem.java b/MCA算法突击课/第03期/mca_04/Code04_EnvelopesProblem.java new file mode 100644 index 0000000..85f6c9b --- /dev/null +++ b/MCA算法突击课/第03期/mca_04/Code04_EnvelopesProblem.java @@ -0,0 +1,41 @@ +package 第03期.mca_04; + +import java.util.Arrays; + +// 给你一个二维整数数组 envelopes +// 其中 envelopes[i] = [wi, hi], 表示第 i 个信封的宽度和高度。 +// 当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里 +// 如同俄罗斯套娃一样 +// 请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封 +// 即可以把一个信封放到另一个信封里面 +// 注意:不允许旋转信封 +// 本题测试链接 : https://leetcode.cn/problems/russian-doll-envelopes/ +public class Code04_EnvelopesProblem { + + public static int maxEnvelopes(int[][] envelopes) { + Arrays.sort(envelopes, (a, b) -> a[0] != b[0] ? (a[0] - b[0]) : (b[1] - a[1])); + int n = envelopes.length; + int[] ends = new int[n]; + ends[0] = envelopes[0][1]; + int right = 0; + int l = 0; + int r = 0; + int m = 0; + for (int i = 1; i < n; i++) { + l = 0; + r = right; + while (l <= r) { + m = (l + r) / 2; + if (envelopes[i][1] > ends[m]) { + l = m + 1; + } else { + r = m - 1; + } + } + right = Math.max(right, l); + ends[l] = envelopes[i][1]; + } + return right + 1; + } + +} diff --git a/MCA算法突击课/第03期/mca_04/Code03_UnionFind.java b/MCA算法突击课/第03期/mca_05/Code03_UnionFind.java similarity index 95% rename from MCA算法突击课/第03期/mca_04/Code03_UnionFind.java rename to MCA算法突击课/第03期/mca_05/Code03_UnionFind.java index 04055b2..9f5c733 100644 --- a/MCA算法突击课/第03期/mca_04/Code03_UnionFind.java +++ b/MCA算法突击课/第03期/mca_05/Code03_UnionFind.java @@ -1,4 +1,4 @@ -package 第03期.mca_04; +package 第03期.mca_05; // 测试链接 : https://www.nowcoder.com/questionTerminal/e7ed657974934a30b2010046536a5372 // 请务必理解这个文件的实现,而且还提供了测试链接 diff --git a/MCA算法突击课/第03期/mca_04/Code04_FriendCircles.java b/MCA算法突击课/第03期/mca_05/Code04_FriendCircles.java similarity index 98% rename from MCA算法突击课/第03期/mca_04/Code04_FriendCircles.java rename to MCA算法突击课/第03期/mca_05/Code04_FriendCircles.java index 2b18236..c63a059 100644 --- a/MCA算法突击课/第03期/mca_04/Code04_FriendCircles.java +++ b/MCA算法突击课/第03期/mca_05/Code04_FriendCircles.java @@ -1,4 +1,4 @@ -package 第03期.mca_04; +package 第03期.mca_05; // 有 n 个城市,其中一些彼此相连,另一些没有相连 // 如果城市 a 与城市 b 直接相连 diff --git a/MCA算法突击课/第03期/mca_04/Code05_CouplesHoldingHands.java b/MCA算法突击课/第03期/mca_05/Code05_CouplesHoldingHands.java similarity index 98% rename from MCA算法突击课/第03期/mca_04/Code05_CouplesHoldingHands.java rename to MCA算法突击课/第03期/mca_05/Code05_CouplesHoldingHands.java index 67765ea..db0aba2 100644 --- a/MCA算法突击课/第03期/mca_04/Code05_CouplesHoldingHands.java +++ b/MCA算法突击课/第03期/mca_05/Code05_CouplesHoldingHands.java @@ -1,4 +1,4 @@ -package 第03期.mca_04; +package 第03期.mca_05; // n对情侣坐在连续排列的 2n 个座位上,想要牵到对方的手 // 人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的ID diff --git a/MCA算法突击课/第03期/mca_04/Code07_LRUCache.java b/MCA算法突击课/第03期/mca_05/Code07_LRUCache.java similarity index 98% rename from MCA算法突击课/第03期/mca_04/Code07_LRUCache.java rename to MCA算法突击课/第03期/mca_05/Code07_LRUCache.java index 7831700..9404699 100644 --- a/MCA算法突击课/第03期/mca_04/Code07_LRUCache.java +++ b/MCA算法突击课/第03期/mca_05/Code07_LRUCache.java @@ -1,4 +1,4 @@ -package 第03期.mca_04; +package 第03期.mca_05; import java.util.HashMap; diff --git a/MCA算法突击课/第03期/ppt/key/第04节.key b/MCA算法突击课/第03期/ppt/key/第04节.key index ccf4538..8b5a87d 100644 Binary files a/MCA算法突击课/第03期/ppt/key/第04节.key and b/MCA算法突击课/第03期/ppt/key/第04节.key differ diff --git a/MCA算法突击课/第03期/ppt/powerpoint/第04节.pptx b/MCA算法突击课/第03期/ppt/powerpoint/第04节.pptx index fcaf1f9..0e7070b 100644 Binary files a/MCA算法突击课/第03期/ppt/powerpoint/第04节.pptx and b/MCA算法突击课/第03期/ppt/powerpoint/第04节.pptx differ