diff --git a/Week_02/id_8/Leetcode_236_8.java b/Week_02/id_8/Leetcode_236_8.java new file mode 100644 index 00000000..06f93c90 --- /dev/null +++ b/Week_02/id_8/Leetcode_236_8.java @@ -0,0 +1,29 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +class Solution { + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) { + return root; + } + if (root == p || root == q) { + 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; + } else if (right != null) { + return right; + } + return null; + } +} \ No newline at end of file diff --git a/Week_02/id_8/Leetcode_242_8.java b/Week_02/id_8/Leetcode_242_8.java new file mode 100644 index 00000000..eff6b838 --- /dev/null +++ b/Week_02/id_8/Leetcode_242_8.java @@ -0,0 +1,33 @@ +class Solution { + public boolean isAnagram(String s, String t) { + // 优化,直接返回false + if (s.length() != t.length()) { + return false; + } + HashMap map = new HashMap<>(); + // 构建hashmap + for (int i = 0; i 这道题目的难点在于单词中可能存在多个相同的字符,常用的简单KV需要使用整数来表示value。 + +### 解题思路 +> 首先可以想到的是,如果两个单词的长度不一致,就直接可以返回false了。 +然后开始构建map, 假设前面单词是a,后面单词是b,则可以以a为标准构建这个map。 +如果存在这个字符,就将该字符的value+1,否则不存在直接置为1。 +然后遍历b,对每一个字符,在前面以a为标准创建出来的map中检查,将存在的那个字符对应的value减一。 +最后只要是不是这个map是不是全是0就行了。 + +### 参考代码AC +```Java +class Solution { + public boolean isAnagram(String s, String t) { + // 优化,直接返回false + if (s.length() != t.length()) { + return false; + } + HashMap map = new HashMap<>(); + // 构建hashmap + for (int i = 0; i这道题的思路挺难想的,可以通过先看答案的方式,理解就行了。 + +### 解题思路 +>这道题本来的解法是这样的,相当于要双重递归了,先DFS每个根节点,然后对每个根节点的左右 + 子树,分别再使用DFS来判断目标节点是否包含在书中。就算使用了一些剪枝的技巧,也超时。然后 + 就想了,是否可以一次递归就搞定,答案是肯定的。 + 优化的思路在于,节点一定都存在,所以只要right == null,就可以断定都在left中,并且祖先就是left + 反之亦然 + +### 参考AC代码 +```Java +class Solution { + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) { + return root; + } + if (root == p || root == q) { + 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; + } else if (right != null) { + return right; + } + return null; + } +} +``` diff --git a/Week_03/id_8/Leetcode_104_8.java b/Week_03/id_8/Leetcode_104_8.java new file mode 100644 index 00000000..e4e25805 --- /dev/null +++ b/Week_03/id_8/Leetcode_104_8.java @@ -0,0 +1,17 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +class Solution { + public int maxDepth(TreeNode root) { + if (root == null) { + return 0; + } + return Math.max(maxDepth(root.left), maxDepth(root.right))+1; + } +} \ No newline at end of file diff --git a/Week_03/id_8/Leetcode_703_8.java b/Week_03/id_8/Leetcode_703_8.java new file mode 100644 index 00000000..b5600b5c --- /dev/null +++ b/Week_03/id_8/Leetcode_703_8.java @@ -0,0 +1,29 @@ +class KthLargest { + + PriorityQueue q; + int k; + + public KthLargest(int k, int[] nums) { + this.k = k; + q = new PriorityQueue(k); + for(int i:nums) { + add(i); + } + } + + public int add(int val) { + if (q.size() < k) { + q.offer(val); + } else if(q.peek() < val) { + q.poll(); + q.offer(val); + } + return q.peek(); + } +} + +/** + * Your KthLargest object will be instantiated and called as such: + * KthLargest obj = new KthLargest(k, nums); + * int param_1 = obj.add(val); + */ \ No newline at end of file diff --git a/Week_03/id_8/NOTE.md b/Week_03/id_8/NOTE.md index 107ea7d6..6dadb86f 100644 --- a/Week_03/id_8/NOTE.md +++ b/Week_03/id_8/NOTE.md @@ -1 +1,77 @@ # 学习笔记 + +### 题目1 + +[Leetcode#104 二叉树的最大深度](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree//) +### 难点分析 +递归的模板定义,终止条件的定义 + +### 解题思路 +> 终止条件:空节点的高度是1 + drill down条件:左右子树递归的返回值的max+1 + +### 参考代码AC +```Java +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +class Solution { + public int maxDepth(TreeNode root) { + if (root == null) { + return 0; + } + return Math.max(maxDepth(root.left), maxDepth(root.right))+1; + } +} +``` + + +### 题目2 +[Leetcode#703 数据流中的第K大元素](https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/) + +### 难点分析 +这道题的难点在于怎样思考到使用小顶堆的模型来抽象这种场景 + +### 解题思路 +> 首先要想到使用堆这种数据结构来抽象这种第K大元素的场景,这种只有靠平时的积累。 +而且要想到使用小顶堆来管理,而小顶堆在java中可以使用一个容量为k的优先队列,就可以很好地 +解决这个问题。因为第K大元素,换句话说其实就是K个的优先队列里面最小的那个元素,就是头指针。 + +### 参考代码AC +```Java +class KthLargest { + + PriorityQueue q; + int k; + + public KthLargest(int k, int[] nums) { + this.k = k; + q = new PriorityQueue(k); + for(int i:nums) { + add(i); + } + } + + public int add(int val) { + if (q.size() < k) { + q.offer(val); + } else if(q.peek() < val) { + q.poll(); + q.offer(val); + } + return q.peek(); + } +} + +/** + * Your KthLargest object will be instantiated and called as such: + * KthLargest obj = new KthLargest(k, nums); + * int param_1 = obj.add(val); + */ +``` \ No newline at end of file diff --git a/Week_04/id_8/Leetcode_455_8.java b/Week_04/id_8/Leetcode_455_8.java new file mode 100644 index 00000000..69043976 --- /dev/null +++ b/Week_04/id_8/Leetcode_455_8.java @@ -0,0 +1,15 @@ +class Solution { + public int findContentChildren(int[] g, int[] s) { + int child = 0; + int cookie = 0; + Arrays.sort(g); + Arrays.sort(s); + while (child < g.length && cookie < s.length ){ + if (g[child] <= s[cookie]){ + child++; + } + cookie++; + } + return child; + } +} \ No newline at end of file diff --git a/Week_04/id_8/Leetcode_70_8(2).java b/Week_04/id_8/Leetcode_70_8(2).java new file mode 100644 index 00000000..6cc08995 --- /dev/null +++ b/Week_04/id_8/Leetcode_70_8(2).java @@ -0,0 +1,16 @@ +class Solution { + public int climbStairs(int n) { + if(n<=0) return 0; + if(n==1) return 1; + if(n==2) return 2; + int one_step_before=2; + int two_step_before=1; + int total=0; + for(int i=3;i<=n;i++){ + total=one_step_before+two_step_before; + two_step_before=one_step_before; + one_step_before=total; + } + return total; + } +} \ No newline at end of file diff --git a/Week_04/id_8/Leetcode_70_8.java b/Week_04/id_8/Leetcode_70_8.java new file mode 100644 index 00000000..b8324268 --- /dev/null +++ b/Week_04/id_8/Leetcode_70_8.java @@ -0,0 +1,22 @@ +class Solution { + HashMap map = new HashMap<>(); + + public int climbStairsHelper(int n, HashMap map) { + if (n == 1) { + return 1; + } + if (n == 2) { + return 2; + } + if (map.containsKey(n)) { + return map.get(n); + } else { + map.put(n,climbStairs(n-2)+climbStairs(n-1)); + return climbStairs(n-2)+climbStairs(n-1); + } + } + + public int climbStairs(int n) { + return climbStairsHelper(n, map); + } +} \ No newline at end of file diff --git a/Week_04/id_8/NOTE.md b/Week_04/id_8/NOTE.md index 107ea7d6..84003147 100644 --- a/Week_04/id_8/NOTE.md +++ b/Week_04/id_8/NOTE.md @@ -1 +1,7 @@ # 学习笔记 + +f(n) = f(n-1)+f(n-2) +分解子问题,f(n-1)和f(-2)解决了,f(n)自然解决了。 + + +比如求 f(3),只要知道f(2)和f(1)的数值,根据递推公式,就能递推出f(3)的值