diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 000000000..39ee28517
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,39 @@
+# Default ignored files
+/workspace.xml
+# Project exclude paths
+/.
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Project exclude paths
+/.
+# Project exclude paths
+/.
+# Project exclude paths
+/.
+# Project exclude paths
+/.
+# Project exclude paths
+/.
+# Project exclude paths
+/.
+# Project exclude paths
+/.
+# Project exclude paths
+/.
+# Project exclude paths
+/.
+# Project exclude paths
+/.
+# Project exclude paths
+/.
\ No newline at end of file
diff --git a/.idea/algorithm010.iml b/.idea/algorithm010.iml
new file mode 100644
index 000000000..b107a2dd8
--- /dev/null
+++ b/.idea/algorithm010.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml
new file mode 100644
index 000000000..2aa056da3
--- /dev/null
+++ b/.idea/google-java-format.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 000000000..6560a9898
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/leetcode/editor.xml b/.idea/leetcode/editor.xml
new file mode 100644
index 000000000..3b3f45c4c
--- /dev/null
+++ b/.idea/leetcode/editor.xml
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 000000000..6c07f54a3
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 000000000..39a5bed6d
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/production/algorithm010/Common/BuildBinaryTree.class b/.idea/production/algorithm010/Common/BuildBinaryTree.class
new file mode 100644
index 000000000..31ec6f8b5
Binary files /dev/null and b/.idea/production/algorithm010/Common/BuildBinaryTree.class differ
diff --git a/.idea/production/algorithm010/Common/TreeNode.class b/.idea/production/algorithm010/Common/TreeNode.class
new file mode 100644
index 000000000..c423450c1
Binary files /dev/null and b/.idea/production/algorithm010/Common/TreeNode.class differ
diff --git a/.idea/production/algorithm010/README.md b/.idea/production/algorithm010/README.md
new file mode 100644
index 000000000..c2f794952
--- /dev/null
+++ b/.idea/production/algorithm010/README.md
@@ -0,0 +1,28 @@
+# 极客大学「算法训练营-第10期」作业提交仓库
+
+
+## 讲师课件下载地址
+
+请大家通过该链接查看讲师课件并进行下载,链接:https://pan.baidu.com/s/1GOuXJfnlERQs8bI8HNwPrQ 密码:zlua
+
+
+## 仓库目录结构说明
+
+1. `week01/` 代表第一周作业提交目录,以此类推。
+2. 请在对应周的目录下新建或修改自己的代码作业。
+2. 每周均有一个 `REDAME.md` 文档,你可以将自己当周的学习心得以及做题过程中的思考记录在该文档中。
+
+## 作业提交规则
+
+1. 先将本仓库 Fork 到自己 GitHub 账号下。
+2. 将 Fork 后的仓库 Clone 到本地,然后在本地仓库中对应周的目录下新建或修改自己的代码作业,当周的学习总结写在对应周的README.md文件里。
+3. 在本地仓库完成作业后,push 到自己的 GitHub 远程仓库。
+4. 最后将远程仓库中当周的作业链接,按格式贴到班级仓库对应学习周的issue下面。
+5. 提交issue请务必按照规定格式进行提交,否则作业统计工具将抓取不到你的作业提交记录。
+
+详细的作业提交流程可以查阅:https://shimo.im/docs/m5rtM8K8rNsjw5jk/
+
+
+## 注意事项
+
+ 如果对 Git 和 GitHub 不太了解,请参考 [Git 官方文档](https://git-scm.com/book/zh/v2) 或者极客时间的[《玩转 Git 三剑客》](https://time.geekbang.org/course/intro/145)视频课程。
diff --git a/.idea/production/algorithm010/Week01/LC189_rotate-array.md b/.idea/production/algorithm010/Week01/LC189_rotate-array.md
new file mode 100644
index 000000000..ec7ca573f
--- /dev/null
+++ b/.idea/production/algorithm010/Week01/LC189_rotate-array.md
@@ -0,0 +1,17 @@
+
+class Solution {
+
+ //Brute-force
+ //move k times for all elements - O(k^n)
+
+ public void rotate(int[] nums, int k) {
+ int length = nums.length;
+ for(int i=0;i0;j--){
+ nums[j] = nums[j-1];
+ }
+ nums[0] = tmp;
+ }
+ }
+}
\ No newline at end of file
diff --git a/.idea/production/algorithm010/Week01/LC206_ReverseLinkedList.md b/.idea/production/algorithm010/Week01/LC206_ReverseLinkedList.md
new file mode 100644
index 000000000..cc4945ef8
--- /dev/null
+++ b/.idea/production/algorithm010/Week01/LC206_ReverseLinkedList.md
@@ -0,0 +1,104 @@
+/*
+第一次写道这样就试着运行,链表和Recursive不清楚 :-)
+*/
+class Solution {
+
+ ListNode res = new ListNode();
+
+ public ListNode reverseList(ListNode head) {
+
+ if (head == null){
+ return null;
+ }
+
+ res.next = head;
+ res = res.next;
+
+ return reverseList(head.next);
+ }
+
+}
+
+//因为要达到末尾时才能够进行连接,所以要在出栈的时候(recursive 调用后)
+class Solution {
+
+ ListNode res = new ListNode();
+
+ public ListNode reverseList(ListNode head) {
+ helper(head);
+ return res;
+ }
+ private ListNode helper(ListNode node){
+ if(node == null || node.next == null){
+ res = node;
+ return node;
+ }
+ ListNode temp = helper(node.next);
+ temp.next = node;
+ node.next = null;
+ return node;
+ }
+}
+
+/*看完题解后:
+1. 迭代法: 用 prev, curr, head 反转指针
+prev = head;
+curr = head.next;
+curr.next = prev; //反转指针
+head = curr;
+
+定义两个指针: pre 和 cur ;pre 在前 cur 在后。
+每次让 pre 的 next 指向 cur ,实现一次局部反转
+局部反转完成之后,pre 和 cur 同时往前移动一个位置
+循环上述过程,直至 pre 到达链表尾部
+
+*/
+class Solution {
+ public ListNode reverseList(ListNode head) {
+ ListNode cur = null, pre=head;
+ while(pre!=null){
+ ListNode tmp = pre.next;
+ pre.next = cur;
+ cur = pre;
+ pre = tmp;
+ }
+ return cur;
+ }
+ //时间复杂度:O(n)O(n)
+ //空间复杂度:O(1)O(1)
+}
+
+/* 2.递归
+递归就是压栈,在递归调用前的code就是压栈前要执行的,在递归调用后的code就是出栈后执行的。
+有没有一种方法/公式,知道是这段代码是放在递归前还是递归后
+ */
+class Solution {
+ public ListNode reverseList(ListNode head) {
+ //terminator
+ if(head == null || head.next == null){
+ return head;
+ }
+ ListNode node = reverseList(head.next); //这里会一直迭代直到触发terminator(走到链表最后),然后才执行下面语句
+ head.next.next = head;
+ head.next = null; //这里是为了断开连接
+ return node;
+ }
+}
+
+/* 递归 2
+ return helper(nextNode, curr); //用value互换来达到指针反转
+ */
+class Solution {
+ public ListNode reverseList(ListNode head) {
+ return helper(head, null);
+ }
+
+ private ListNode helper(ListNode curr, ListNode newList){
+ if (curr == null){
+ return newList;
+ }
+ ListNode nextNode = curr.next;
+ curr.next = newList;
+ return helper(nextNode, curr); //用参数互换来达到指针反转
+ }
+}
\ No newline at end of file
diff --git a/.idea/production/algorithm010/Week01/LC21_merge-two-sorted-lists.md b/.idea/production/algorithm010/Week01/LC21_merge-two-sorted-lists.md
new file mode 100644
index 000000000..a84347b6d
--- /dev/null
+++ b/.idea/production/algorithm010/Week01/LC21_merge-two-sorted-lists.md
@@ -0,0 +1,30 @@
+
+class Solution {
+
+ /*
+ 思路
+
+ 终止条件:两条链表分别名为 l1 和 l2,当 l1 为空或 l2 为空时结束
+ 返回值:每一层调用都返回排序好的链表头
+ 本级递归内容:如果 l1 的 val 值更小,则将 l1.next 与排序好的链表头相接,l2 同理
+ O(m+n)O(m+n),mm 为 l1的长度,nn 为 l2 的长度
+ */
+
+ public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
+ //terminator:
+ if(l1 == null){
+ return l2;
+ }
+ if(l2 == null){
+ return l1;
+ }
+ if (l1.val < l2.val){
+ l1.next = mergeTwoLists(l1.next, l2);
+ return l1;
+ }
+ else {
+ l2.next = mergeTwoLists(l1, l2.next);
+ return l2;
+ }
+ }
+}
\ No newline at end of file
diff --git a/.idea/production/algorithm010/Week01/LC26_remove-duplicates-from-sorted-array.md b/.idea/production/algorithm010/Week01/LC26_remove-duplicates-from-sorted-array.md
new file mode 100644
index 000000000..7c440b78b
--- /dev/null
+++ b/.idea/production/algorithm010/Week01/LC26_remove-duplicates-from-sorted-array.md
@@ -0,0 +1,21 @@
+
+class Solution {
+
+
+ //代替法,用j保存修改数组的位置
+
+ public int removeDuplicates(int[] nums) {
+ if (nums == null || nums.length==0){
+ return 0;
+ }
+ int j =0;
+ for(int i=0;i=0) {
+ // when nums1 reach the head, p1 will become -1
+ if (p1 == -1 || nums1[p1] <= nums2[p2]) {
+ nums1[p] = nums2[p2];
+ p2--;
+ }
+ else{
+ nums1[p] = nums1[p1];
+ p1--;
+ }
+ p--;
+
+ nums1[p--] = (p1 == -1 || nums1[p1] <= nums2[p2]) ? nums2[p2--] : nums1[p1--];
+ }
+ }
+}
+
+//可以简化成四行
+class Solution {
+ public void merge(int[] nums1, int m, int[] nums2, int n) {
+ int p1 = m - 1, p2 = n - 1, p = m + n - 1;
+ while (p2 >= 0) {
+ nums1[p--] = (p1 == -1 || nums1[p1] <= nums2[p2]) ? nums2[p2--] : nums1[p1--];
+ }
+ }
+}
\ No newline at end of file
diff --git a/.idea/production/algorithm010/Week01/LC_283_MoveZeroes.md b/.idea/production/algorithm010/Week01/LC_283_MoveZeroes.md
new file mode 100644
index 000000000..500ef6dbb
--- /dev/null
+++ b/.idea/production/algorithm010/Week01/LC_283_MoveZeroes.md
@@ -0,0 +1,47 @@
+class Solution {
+
+
+ public void moveZeroes(int[] nums) {
+ //把0用后面的数代替,并统计0的个数记录在j上
+ int j =0;
+ for(int i=0;i=0;i--){
+ digits[i]++;
+ digits[i] = digits[i] % 10;
+ //e.g. 1,9,9; when it becomes 200. it will end th loop
+ if (digits[i] != 0) return digits;
+ }
+ // reach here, only when all digits are 9. e.g. 999
+ // in java, int[] initia with '0'
+ int[] newDigits = new int[digits.length +1];
+ // System.arraycopy(digits,0,newDigits,1,digits.length);
+ newDigits[0] = 1;
+ return newDigits;
+
+ }
+}
\ No newline at end of file
diff --git a/.idea/production/algorithm010/Week01/LeetCode_11.md b/.idea/production/algorithm010/Week01/LeetCode_11.md
new file mode 100644
index 000000000..96824c7e6
--- /dev/null
+++ b/.idea/production/algorithm010/Week01/LeetCode_11.md
@@ -0,0 +1,27 @@
+class Solution {
+
+
+ //11. 盛最多水的容器
+
+ public int maxArea(int[] height) {
+
+ int len = height.length;
+ int i=0, j=len-1,h=0;
+ int maxArea =0;
+
+ while (i> threeSum(int[] nums) {
+ List> result = new ArrayList<>();
+ int len = nums.length;
+ if (nums == null || len<3) {
+ return result;
+ }
+ //sort是关键,排序完就很容易去重了
+ Arrays.sort(nums);
+
+ for (int i=0;i0 && nums[i] == nums[i-1]) continue;
+ //用while一样效果,不用回到for去判断
+ while (i>0 && i0) break;
+
+ int left = i+1;
+ int right = len-1;
+ while (left stack = new LinkedList();
+ stack.addFirst("a");
+ stack.addFirst("b");
+ stack.addFirst("c");
+ System.out.println(stack);
+
+ String str = stack.peek();
+ System.out.println(str);
+ System.out.println(stack);
+ while (stack.size()>0){
+ System.out.println(stack.removeFirst());
+ }
+ System.out.println(stack);
+
diff --git a/.idea/production/algorithm010/Week02/BinanryTree_Traversal$TreeNode.class b/.idea/production/algorithm010/Week02/BinanryTree_Traversal$TreeNode.class
new file mode 100644
index 000000000..1508b2f1e
Binary files /dev/null and b/.idea/production/algorithm010/Week02/BinanryTree_Traversal$TreeNode.class differ
diff --git a/.idea/production/algorithm010/Week02/BinanryTree_Traversal.class b/.idea/production/algorithm010/Week02/BinanryTree_Traversal.class
new file mode 100644
index 000000000..30fd3db6a
Binary files /dev/null and b/.idea/production/algorithm010/Week02/BinanryTree_Traversal.class differ
diff --git a/.idea/production/algorithm010/Week02/BinaryHeap.class b/.idea/production/algorithm010/Week02/BinaryHeap.class
new file mode 100644
index 000000000..fa9e64fc0
Binary files /dev/null and b/.idea/production/algorithm010/Week02/BinaryHeap.class differ
diff --git "a/.idea/production/algorithm010/Week02/HashMap\346\200\273\347\273\223.md" "b/.idea/production/algorithm010/Week02/HashMap\346\200\273\347\273\223.md"
new file mode 100644
index 000000000..465cb6d27
--- /dev/null
+++ "b/.idea/production/algorithm010/Week02/HashMap\346\200\273\347\273\223.md"
@@ -0,0 +1,161 @@
+一,HashMap的内部存储结构
+
+Java中数据存储方式最底层的两种结构,一种是数组,另一种就是链表。
+
+数组的特点:连续空间,寻址迅速,但是在删除或者添加元素的时候需要有较大幅度的移动,所以查询速度快,增删较慢。
+链表的特点:由于空间不连续,寻址困难,增删元素只需修改指针,所以查询慢、增删快。
+综合这两者的优点,摒弃缺点,哈希表就诞生了,既满足了数据查找方面的特点,占用的空间也不大。
+
+二、底层原理
+
+HashMap的实现主要用到了哈希表的链地址法。即使用数组+链表的方式实现。
+hashMap实现了Map接口,继承了AbstractMap类。其中Map接口定义了键映射到值的规则,AbstractMap类提供了Map接口的骨干实现。
+hashMap底层有一个entry数组(entry是hashMap的内部类,它包含了键key、值value、下一个节点next,以及hash值,
+正是由于Entry才构成了table数组的项为链表),数组上每一项都有一个链表,如果链表长度超过阀值( TREEIFY THRESHOLD==8),就把链表转成红黑树,链表长度低于6,就把红黑树转回链表
+
+JDK 1.7 有源码分析
+三、HashMap提供的三个构造函数:
+
+1、HashMap():
+构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
+
+2、HashMap(int initialCapacity):
+构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
+
+3、HashMap(int initialCapacity, float loadFactor):
+构造一个带指定初始容量和加载因子的空 HashMap。
+
+常量
+static final int DEFAULT_INITIAL_CAPACITY = 16;
+初始容量:16
+static final int MAXIMUM_CAPACITY = 1 << 30;
+最大容量:2的30次方 => 1073741824
+static final float DEFAULT_LOAD_FACTOR = 0.75f;
+负载因子:75%
+
+** put(Object key,Object value)方法:
+
+作用是存储一个键-值对
+
+ public V put(K key, V value) {
+ if (key == null)
+ return putForNullKey(value);
+ int hash = hash(key.hashCode());
+ int i = indexFor(hash, table.length);
+ for (Entry e = table[i]; e != null; e = e.next) {
+ Object k;
+ if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
+ V oldValue = e.value;
+ e.value = value;
+ e.recordAccess(this);
+ return oldValue;
+ }
+ }
+
+ modCount++;
+ addEntry(hash, key, value, i);
+ return null;
+ }
+
+ 处理步骤如下:
+ (1)判断key是否为null,若为null,调用putForNullKey(value)处理。这个方法代码如下:
+
+ /**
+ * Offloaded version of put for null keys
+ */
+ private V putForNullKey(V value) {
+ for (Entry e = table[0]; e != null; e = e.next) {
+ if (e.key == null) {
+ V oldValue = e.value;
+ e.value = value;
+ e.recordAccess(this);
+ return oldValue;
+ }
+ }
+ modCount++;
+ addEntry(0, null, value, 0);
+ return null;
+ }
+
+
+从代码可以看出,如果key为null的值,默认就存储到table[0]开头的链表了。然后遍历table[0]的链表的每个节点Entry,
+如果发现其中存在节点Entry的key为null,就替换新的value,然后返回旧的value,
+如果没发现key等于null的节点Entry,就增加新的节点。
+
+(2)先计算key的hashcode,在使用计算的结果二次hash,使用indexFor(hash, table.length)方法找到Entry数组的索引i的位置。
+
+(3)接着遍历以table[i]为头结点的链表,如果发现已经存在节点的hash、key值与条件相同时,
+将该节点的value值替换为新的value值,然后返回旧的value值。
+
+(4)如果未找到hash、key值均相同的节点,则调用addEntry方法增加新的节点(头插法)。代码如下:
+
+ void addEntry(int hash, K key, V value, int bucketIndex) {
+ Entry e = table[bucketIndex];
+ table[bucketIndex] = new Entry(hash, key, value, e);
+ if (size++ >= threshold)
+ resize(2 * table.length);
+ }
+
+
+**get(Object key)方法:
+
+作用是根据键来获取值
+
+ public V get(Object key) {
+ if (key == null)
+ return getForNullKey();
+ int hash = hash(key.hashCode());
+ for (Entry e = table[indexFor(hash, table.length)];
+ e != null;
+ e = e.next) {
+ Object k;
+ if (e.hash == hash && ((k = e.key) == key || key.equals(k)))//-------------------1----------------
+ return e.value;
+ }
+ return null;
+ }
+
+
+处理步骤如下:
+(1)当key为null时,调用getForNullKey(),它的源码如下:
+
+ private V getForNullKey() {
+ for (Entry e = table[0]; e != null; e = e.next) {
+ if (e.key == null)
+ return e.value;
+ }
+ return null;
+ }
+
+返回table[0]开头的链表的键为null的节点的值
+
+(2)当键不为null时,依然计算hash值,然后找到具体在哪个table[indexFor(hash, table.length)]
+节点开头的链表中,遍历此链表查找是否存在搜索条件中的key值,返回其value。若没有符合条件的key值,返回null。
+
+
+***HashMap常考问题总结
+
+最后补充一些面试时候常问到的一些问题总结。
+
+(1)HashMap和HashTable的区别?
+
+HashMap是非线程安全的,HashTable是线程安全的
+HashMap的键和值都允许有null值存在,而HashTable则不行
+因为线程安全的问题,HashMap效率比HashTable的要高
+哈希值的使用不同,HashMap要根据hashCode二次计算得到hash值,而HashTable直接使用对象的hashCode
+继承的父类不同,HashMap继承自AbstractMap,而HashTable继承自Dictionary
+
+(2)HashMap中的键可以是任何对象或数据类型吗?
+
+可以为null,但是不能为可变对象。如果为可变对象的话,对象中的属性改变则对象的hashCode也进行了相应的改变,导致下次无法查找到已存在Map中的数据。
+如果可变对象在HashMap中被当做键,那么就要小心在它的属性改变时,不要改变它的hashCode。只要保证成员变量的改变不会相应改变其hashCode即可。
+
+(3)HashTable如何实现线程安全?
+
+实现原理是在对应的方法上添加了synchronized关键字进行修饰,由于在执行此方法时需要获得对象锁,
+因此执行起来比较慢。如果想实现线程安全的HashMap的话,推荐使用ConcurrentHashMap。
+
+
+参考资料:
+链接:https://www.jianshu.com/p/2f50d21dbfdc
+
diff --git a/.idea/production/algorithm010/Week02/LC_200_number_of_islands.class b/.idea/production/algorithm010/Week02/LC_200_number_of_islands.class
new file mode 100644
index 000000000..bc026d83e
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_200_number_of_islands.class differ
diff --git a/.idea/production/algorithm010/Week02/LC_22_generate_parentheses$Node.class b/.idea/production/algorithm010/Week02/LC_22_generate_parentheses$Node.class
new file mode 100644
index 000000000..9d8411f6f
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_22_generate_parentheses$Node.class differ
diff --git a/.idea/production/algorithm010/Week02/LC_22_generate_parentheses.class b/.idea/production/algorithm010/Week02/LC_22_generate_parentheses.class
new file mode 100644
index 000000000..b3e7969e8
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_22_generate_parentheses.class differ
diff --git a/.idea/production/algorithm010/Week02/LC_239_sliding_window_maximum.class b/.idea/production/algorithm010/Week02/LC_239_sliding_window_maximum.class
new file mode 100644
index 000000000..99251d039
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_239_sliding_window_maximum.class differ
diff --git a/.idea/production/algorithm010/Week02/LC_242_valid_anagram.class b/.idea/production/algorithm010/Week02/LC_242_valid_anagram.class
new file mode 100644
index 000000000..1842b497b
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_242_valid_anagram.class differ
diff --git a/.idea/production/algorithm010/Week02/LC_264_ugly_number_ii.class b/.idea/production/algorithm010/Week02/LC_264_ugly_number_ii.class
new file mode 100644
index 000000000..a375b104c
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_264_ugly_number_ii.class differ
diff --git a/.idea/production/algorithm010/Week02/LC_347_top_k_frequent_elements$1.class b/.idea/production/algorithm010/Week02/LC_347_top_k_frequent_elements$1.class
new file mode 100644
index 000000000..4a9be3536
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_347_top_k_frequent_elements$1.class differ
diff --git a/.idea/production/algorithm010/Week02/LC_347_top_k_frequent_elements.class b/.idea/production/algorithm010/Week02/LC_347_top_k_frequent_elements.class
new file mode 100644
index 000000000..1c0b1f4c1
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_347_top_k_frequent_elements.class differ
diff --git a/.idea/production/algorithm010/Week02/LC_49_Group_anagrams.class b/.idea/production/algorithm010/Week02/LC_49_Group_anagrams.class
new file mode 100644
index 000000000..220223e1c
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_49_Group_anagrams.class differ
diff --git a/.idea/production/algorithm010/Week02/LC_m40_small_k_digits.class b/.idea/production/algorithm010/Week02/LC_m40_small_k_digits.class
new file mode 100644
index 000000000..d4f7ca5df
Binary files /dev/null and b/.idea/production/algorithm010/Week02/LC_m40_small_k_digits.class differ
diff --git a/.idea/production/algorithm010/Week02/NOTE.md b/.idea/production/algorithm010/Week02/NOTE.md
new file mode 100644
index 000000000..d6635abf7
--- /dev/null
+++ b/.idea/production/algorithm010/Week02/NOTE.md
@@ -0,0 +1,94 @@
+学习笔记
+ArrayList / List 初始化:
+List list = Arrays.asList(1,2);
+
+Array 初始化:
+int[]{map.get(target-nums[i]),nums[i]};
+
+HashMap 源码:
+为啥要这么多中间变量呢? tab, first, e; n,k 感觉诚心让我们不容易看懂源码:-)
+这些中间变量的作用是存储取出的值? tab = table 有啥作用,为啥不能直接在table上操作?
+
+putVal时,如果hash key 相同的值超过7个时变为TreeNode(红黑树)
+ if (binCount >= 7) { this.treeifyBin(tab, hash); }
+---------------------------------------------
+ final Node getNode(int hash, Object key) {
+ Node[] tab; Node first, e; int n; K k;
+ if ((tab = table) != null && (n = tab.length) > 0 &&
+ (first = tab[(n - 1) & hash]) != null) {
+ if (first.hash == hash && // always check first node
+ ((k = first.key) == key || (key != null && key.equals(k))))
+ return first;
+ if ((e = first.next) != null) {
+ if (first instanceof TreeNode)
+ return ((TreeNode)first).getTreeNode(hash, key);
+ do {
+ if (e.hash == hash &&
+ ((k = e.key) == key || (key != null && key.equals(k))))
+ return e;
+ } while ((e = e.next) != null);
+ }
+ }
+ return null;
+ }
+
+------------------------
+
+ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
+ HashMap.Node[] tab;
+ int n;
+ if ((tab = this.table) == null || (n = tab.length) == 0) {
+ n = (tab = this.resize()).length;
+ }
+
+ Object p;
+ int i;
+ if ((p = tab[i = n - 1 & hash]) == null) {
+ tab[i] = this.newNode(hash, key, value, (HashMap.Node)null);
+ } else {
+ Object e;
+ Object k;
+ if (((HashMap.Node)p).hash == hash && ((k = ((HashMap.Node)p).key) == key || key != null && key.equals(k))) {
+ e = p;
+ } else if (p instanceof HashMap.TreeNode) {
+ e = ((HashMap.TreeNode)p).putTreeVal(this, tab, hash, key, value);
+ } else {
+ int binCount = 0;
+
+ while(true) {
+ if ((e = ((HashMap.Node)p).next) == null) {
+ ((HashMap.Node)p).next = this.newNode(hash, key, value, (HashMap.Node)null);
+ if (binCount >= 7) {
+ this.treeifyBin(tab, hash);
+ }
+ break;
+ }
+
+ if (((HashMap.Node)e).hash == hash && ((k = ((HashMap.Node)e).key) == key || key != null && key.equals(k))) {
+ break;
+ }
+
+ p = e;
+ ++binCount;
+ }
+ }
+
+ if (e != null) {
+ V oldValue = ((HashMap.Node)e).value;
+ if (!onlyIfAbsent || oldValue == null) {
+ ((HashMap.Node)e).value = value;
+ }
+
+ this.afterNodeAccess((HashMap.Node)e);
+ return oldValue;
+ }
+ }
+
+ ++this.modCount;
+ if (++this.size > this.threshold) {
+ this.resize();
+ }
+
+ this.afterNodeInsertion(evict);
+ return null;
+ }
diff --git a/.idea/production/algorithm010/Week02/test.class b/.idea/production/algorithm010/Week02/test.class
new file mode 100644
index 000000000..e427b2b9e
Binary files /dev/null and b/.idea/production/algorithm010/Week02/test.class differ
diff --git "a/.idea/production/algorithm010/Week03/.NOTE_images/\345\233\236\346\234\224\347\256\227\346\263\225.png" "b/.idea/production/algorithm010/Week03/.NOTE_images/\345\233\236\346\234\224\347\256\227\346\263\225.png"
new file mode 100644
index 000000000..1cbd75499
Binary files /dev/null and "b/.idea/production/algorithm010/Week03/.NOTE_images/\345\233\236\346\234\224\347\256\227\346\263\225.png" differ
diff --git a/.idea/production/algorithm010/Week03/LC105_construct_binary_tree_from_preorder$TreeNode.class b/.idea/production/algorithm010/Week03/LC105_construct_binary_tree_from_preorder$TreeNode.class
new file mode 100644
index 000000000..ca0cb93c2
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC105_construct_binary_tree_from_preorder$TreeNode.class differ
diff --git a/.idea/production/algorithm010/Week03/LC105_construct_binary_tree_from_preorder.class b/.idea/production/algorithm010/Week03/LC105_construct_binary_tree_from_preorder.class
new file mode 100644
index 000000000..c08d42731
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC105_construct_binary_tree_from_preorder.class differ
diff --git a/.idea/production/algorithm010/Week03/LC111_min_depth_b_tree.class b/.idea/production/algorithm010/Week03/LC111_min_depth_b_tree.class
new file mode 100644
index 000000000..1123f66f5
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC111_min_depth_b_tree.class differ
diff --git a/.idea/production/algorithm010/Week03/LC236_lowest_common_ancestor$TreeNode.class b/.idea/production/algorithm010/Week03/LC236_lowest_common_ancestor$TreeNode.class
new file mode 100644
index 000000000..20dac47ff
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC236_lowest_common_ancestor$TreeNode.class differ
diff --git a/.idea/production/algorithm010/Week03/LC236_lowest_common_ancestor.class b/.idea/production/algorithm010/Week03/LC236_lowest_common_ancestor.class
new file mode 100644
index 000000000..8382e98c7
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC236_lowest_common_ancestor.class differ
diff --git a/.idea/production/algorithm010/Week03/LC46_permutations.class b/.idea/production/algorithm010/Week03/LC46_permutations.class
new file mode 100644
index 000000000..6be9c2f9e
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC46_permutations.class differ
diff --git a/.idea/production/algorithm010/Week03/LC47_permutations_ii.class b/.idea/production/algorithm010/Week03/LC47_permutations_ii.class
new file mode 100644
index 000000000..10398ffc5
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC47_permutations_ii.class differ
diff --git a/.idea/production/algorithm010/Week03/LC51_n_queens.class b/.idea/production/algorithm010/Week03/LC51_n_queens.class
new file mode 100644
index 000000000..58132298a
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC51_n_queens.class differ
diff --git a/.idea/production/algorithm010/Week03/LC_17_Letter_combinations_of_phone$1.class b/.idea/production/algorithm010/Week03/LC_17_Letter_combinations_of_phone$1.class
new file mode 100644
index 000000000..63847311e
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC_17_Letter_combinations_of_phone$1.class differ
diff --git a/.idea/production/algorithm010/Week03/LC_17_Letter_combinations_of_phone.class b/.idea/production/algorithm010/Week03/LC_17_Letter_combinations_of_phone.class
new file mode 100644
index 000000000..28f9a1dc2
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC_17_Letter_combinations_of_phone.class differ
diff --git a/.idea/production/algorithm010/Week03/LC_50_powx_n.class b/.idea/production/algorithm010/Week03/LC_50_powx_n.class
new file mode 100644
index 000000000..b3ad63236
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC_50_powx_n.class differ
diff --git a/.idea/production/algorithm010/Week03/LC_77_combinations.class b/.idea/production/algorithm010/Week03/LC_77_combinations.class
new file mode 100644
index 000000000..e671d1266
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC_77_combinations.class differ
diff --git a/.idea/production/algorithm010/Week03/LC_78_subsets.class b/.idea/production/algorithm010/Week03/LC_78_subsets.class
new file mode 100644
index 000000000..5dcbe1486
Binary files /dev/null and b/.idea/production/algorithm010/Week03/LC_78_subsets.class differ
diff --git a/.idea/production/algorithm010/Week03/Lc_69_sqrtx.class b/.idea/production/algorithm010/Week03/Lc_69_sqrtx.class
new file mode 100644
index 000000000..8cda4f70d
Binary files /dev/null and b/.idea/production/algorithm010/Week03/Lc_69_sqrtx.class differ
diff --git a/.idea/production/algorithm010/Week03/NOTE.md b/.idea/production/algorithm010/Week03/NOTE.md
new file mode 100644
index 000000000..3227948df
--- /dev/null
+++ b/.idea/production/algorithm010/Week03/NOTE.md
@@ -0,0 +1,116 @@
+#学习笔记
+----
+###Java 递归模板
+• 递归终结条件
+• 处理当前层逻辑
+• 下探到下一层
+• 清理当前层
+``` Java
+ public void recur(int level, int param) {
+ //terminator
+ if (level > MAX_LEVEL) {
+ //process result
+ return;
+ }
+
+ //process current logic
+ process(level, param);
+
+ //drill down
+ recur(level: level+1,newParam);
+
+ //restore current status
+
+ }
+```
+###递归思维要点
+• 不要人肉递归(最大误区)
+• 找到最近最简方法,将其拆解成可以重复解决的问题(重复子问题)
+• 数学归纳法
+
+分治的递归模板 Didide & Conquer template:
+
+ //1. terminator
+ //2. process (split your big problem)
+ //3. drill down (sub-problems)
+ //4. merge(sub-result)
+ //5. reverse states
+
+ # Python
+ def divide_conquer(problem, param1, param2, ...):
+ # recursion terminator
+ if problem is None:
+ print_result
+ return
+ # prepare data
+ data = prepare_data(problem)
+ subproblems = split_problem(problem, data)
+ # conquer subproblems
+ subresult1 = self.divide_conquer(subproblems[0], p1, ...)
+ subresult2 = self.divide_conquer(subproblems[1], p1, ...)
+ subresult3 = self.divide_conquer(subproblems[2], p1, ...)
+ …
+ # process and generate the final result
+ result = process_result(subresult1, subresult2, subresult3, …)
+
+ # revert the current level states
+
+
+###回溯
+ 每一层不断尝试,以获取可能的解
+ 只需要思考 3 个问题:
+ 1、路径:也就是已经做出的选择。
+ 2、选择列表:也就是你当前可以做的选择。
+ 3、结束条件:也就是到达决策树底层,无法再做选择的条件。
+
+ 回溯模板:
+
+ ```
+ result = [];
+ public void backtrack(路径, 选择列表){
+ if 满足结束条件:
+ result.add(路径);
+ return;
+
+ for 选择 in 选择列表:
+ 做选择;
+ backtrack(路径, 选择列表);
+ 撤销选择;
+ }
+ ```
+ 其核心就是 for 循环里面的递归,在递归调用之前「做选择」,在递归调用之后「撤销选择」
+
+ 列题:反转链表:
+ 这个BFS的讨论想和大家再重申一下
+ 1. 初始化一个队列
+ 2. 队列中先把第一个节点放进去,作为启动节点,不然后面没法while启动起来
+ 3. 队列中出一个节点,处理,然后把它的所有子节点拿出来,依次放入队列中
+ ###
+ 总结
+ 1. 初始节点在循环外放进去
+ 2. 处理节点逻辑和生成子节点逻辑放到循环内
+
+我做题的时候,第 1 步都是先画图,画图是非常重要的,只有画图才能帮助我们想清楚递归结构,想清楚如何剪枝。就拿题目中的示例,想一想人手动操作是怎么做的,一般这样下来,这棵递归树都不难画出。
+即在画图的过程中思考清楚:
+
+1、分支如何产生;
+2、题目需要的解在哪里?是在叶子结点、还是在非叶子结点、还是在从跟结点到叶子结点的路径?
+3、哪些搜索是会产生不需要的解的?例如:产生重复是什么原因,如果在浅层就知道这个分支不能产生需要的结果,应该提前剪枝,剪枝的条件是什么,代码怎么写?
+
+
+题目 提示
+47. 全排列 II 思考一下,为什么造成了重复,如何在搜索之前就判断这一支会产生重复,从而“剪枝”。
+17 .电话号码的字母组合
+22. 括号生成 这是字符串问题,没有显式回溯的过程。这道题广度优先遍历也很好写,可以通过这个问题理解一下为什么回溯算法都是深度优先遍历,并且都用递归来写。
+39. 组合总和 使用题目给的示例,画图分析。
+40. 组合总和 II
+51. N皇后 其实就是全排列问题,注意设计清楚状态变量。
+60. 第k个排列 利用了剪枝的思想,减去了大量枝叶,直接来到需要的叶子结点。
+77. 组合 组合问题按顺序找,就不会重复。并且举一个中等规模的例子,找到如何剪枝,这道题思想不难,难在编码。
+78. 子集 为数不多的,解不在叶子结点上的回溯搜索问题。解法比较多,注意对比。
+90. 子集 II 剪枝技巧同 47 题、39 题、40 题。
+93. 复原IP地址
+784. 字母大小写全排列
+
+作者:liweiwei1419
+链接:https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/
\ No newline at end of file
diff --git a/.idea/production/algorithm010/Week03/Solution.class b/.idea/production/algorithm010/Week03/Solution.class
new file mode 100644
index 000000000..4ed7fae6f
Binary files /dev/null and b/.idea/production/algorithm010/Week03/Solution.class differ
diff --git a/.idea/production/algorithm010/Week03/Test.class b/.idea/production/algorithm010/Week03/Test.class
new file mode 100644
index 000000000..1bb330bc8
Binary files /dev/null and b/.idea/production/algorithm010/Week03/Test.class differ
diff --git a/.idea/production/algorithm010/Week04/.NOTE_images/bfs-dfs.png b/.idea/production/algorithm010/Week04/.NOTE_images/bfs-dfs.png
new file mode 100644
index 000000000..ef4faed9a
Binary files /dev/null and b/.idea/production/algorithm010/Week04/.NOTE_images/bfs-dfs.png differ
diff --git a/.idea/production/algorithm010/Week04/Amazon_Interview.class b/.idea/production/algorithm010/Week04/Amazon_Interview.class
new file mode 100644
index 000000000..3f816fc94
Binary files /dev/null and b/.idea/production/algorithm010/Week04/Amazon_Interview.class differ
diff --git a/.idea/production/algorithm010/Week04/LC102_binary_tree_level_order_traversal.class b/.idea/production/algorithm010/Week04/LC102_binary_tree_level_order_traversal.class
new file mode 100644
index 000000000..2802e3637
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC102_binary_tree_level_order_traversal.class differ
diff --git a/.idea/production/algorithm010/Week04/LC122_best_time_to_buy_sell_stock_ii$Solution.class b/.idea/production/algorithm010/Week04/LC122_best_time_to_buy_sell_stock_ii$Solution.class
new file mode 100644
index 000000000..5599791e9
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC122_best_time_to_buy_sell_stock_ii$Solution.class differ
diff --git a/.idea/production/algorithm010/Week04/LC122_best_time_to_buy_sell_stock_ii.class b/.idea/production/algorithm010/Week04/LC122_best_time_to_buy_sell_stock_ii.class
new file mode 100644
index 000000000..76150d0c7
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC122_best_time_to_buy_sell_stock_ii.class differ
diff --git a/.idea/production/algorithm010/Week04/LC126_word_ladder_ii$Solution.class b/.idea/production/algorithm010/Week04/LC126_word_ladder_ii$Solution.class
new file mode 100644
index 000000000..2d12a3ed4
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC126_word_ladder_ii$Solution.class differ
diff --git a/.idea/production/algorithm010/Week04/LC126_word_ladder_ii.class b/.idea/production/algorithm010/Week04/LC126_word_ladder_ii.class
new file mode 100644
index 000000000..8923a1a4b
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC126_word_ladder_ii.class differ
diff --git a/.idea/production/algorithm010/Week04/LC127_word_ladder$Solution.class b/.idea/production/algorithm010/Week04/LC127_word_ladder$Solution.class
new file mode 100644
index 000000000..ca6875cfe
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC127_word_ladder$Solution.class differ
diff --git a/.idea/production/algorithm010/Week04/LC127_word_ladder$Solution2.class b/.idea/production/algorithm010/Week04/LC127_word_ladder$Solution2.class
new file mode 100644
index 000000000..9e2f4b957
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC127_word_ladder$Solution2.class differ
diff --git a/.idea/production/algorithm010/Week04/LC127_word_ladder.class b/.idea/production/algorithm010/Week04/LC127_word_ladder.class
new file mode 100644
index 000000000..8aba8532f
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC127_word_ladder.class differ
diff --git a/.idea/production/algorithm010/Week04/LC153_find_minimum_in_rotated_sorted_array$Solution.class b/.idea/production/algorithm010/Week04/LC153_find_minimum_in_rotated_sorted_array$Solution.class
new file mode 100644
index 000000000..2a508983d
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC153_find_minimum_in_rotated_sorted_array$Solution.class differ
diff --git a/.idea/production/algorithm010/Week04/LC153_find_minimum_in_rotated_sorted_array.class b/.idea/production/algorithm010/Week04/LC153_find_minimum_in_rotated_sorted_array.class
new file mode 100644
index 000000000..d20fffcd9
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC153_find_minimum_in_rotated_sorted_array.class differ
diff --git a/.idea/production/algorithm010/Week04/LC33_search_in_rotated_sorted_array.class b/.idea/production/algorithm010/Week04/LC33_search_in_rotated_sorted_array.class
new file mode 100644
index 000000000..7fe1a7f25
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC33_search_in_rotated_sorted_array.class differ
diff --git a/.idea/production/algorithm010/Week04/LC367_valid_perfect_square$Solution.class b/.idea/production/algorithm010/Week04/LC367_valid_perfect_square$Solution.class
new file mode 100644
index 000000000..7fb306594
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC367_valid_perfect_square$Solution.class differ
diff --git a/.idea/production/algorithm010/Week04/LC367_valid_perfect_square.class b/.idea/production/algorithm010/Week04/LC367_valid_perfect_square.class
new file mode 100644
index 000000000..881d331e6
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC367_valid_perfect_square.class differ
diff --git a/.idea/production/algorithm010/Week04/LC455_assign_cookies.class b/.idea/production/algorithm010/Week04/LC455_assign_cookies.class
new file mode 100644
index 000000000..f2752ac3a
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC455_assign_cookies.class differ
diff --git a/.idea/production/algorithm010/Week04/LC45_jump_game_ii$Solution.class b/.idea/production/algorithm010/Week04/LC45_jump_game_ii$Solution.class
new file mode 100644
index 000000000..343bfde4f
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC45_jump_game_ii$Solution.class differ
diff --git a/.idea/production/algorithm010/Week04/LC45_jump_game_ii.class b/.idea/production/algorithm010/Week04/LC45_jump_game_ii.class
new file mode 100644
index 000000000..b02bbc426
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC45_jump_game_ii.class differ
diff --git a/.idea/production/algorithm010/Week04/LC529_minesweeper$Solution.class b/.idea/production/algorithm010/Week04/LC529_minesweeper$Solution.class
new file mode 100644
index 000000000..6db1c06d1
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC529_minesweeper$Solution.class differ
diff --git a/.idea/production/algorithm010/Week04/LC529_minesweeper.class b/.idea/production/algorithm010/Week04/LC529_minesweeper.class
new file mode 100644
index 000000000..d3eeef94a
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC529_minesweeper.class differ
diff --git a/.idea/production/algorithm010/Week04/LC55_jump_game.class b/.idea/production/algorithm010/Week04/LC55_jump_game.class
new file mode 100644
index 000000000..ef06fcc36
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC55_jump_game.class differ
diff --git a/.idea/production/algorithm010/Week04/LC69_sqrtx.class b/.idea/production/algorithm010/Week04/LC69_sqrtx.class
new file mode 100644
index 000000000..d02480f6a
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC69_sqrtx.class differ
diff --git a/.idea/production/algorithm010/Week04/LC74_search_2d_matrix.class b/.idea/production/algorithm010/Week04/LC74_search_2d_matrix.class
new file mode 100644
index 000000000..4dd34228a
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC74_search_2d_matrix.class differ
diff --git a/.idea/production/algorithm010/Week04/LC850_lemonade_change.class b/.idea/production/algorithm010/Week04/LC850_lemonade_change.class
new file mode 100644
index 000000000..f63ce4fea
Binary files /dev/null and b/.idea/production/algorithm010/Week04/LC850_lemonade_change.class differ
diff --git a/.idea/production/algorithm010/Week04/NOTE.md b/.idea/production/algorithm010/Week04/NOTE.md
new file mode 100644
index 000000000..db5f1b923
--- /dev/null
+++ b/.idea/production/algorithm010/Week04/NOTE.md
@@ -0,0 +1,108 @@
+学习笔记
+#贪心:
+当下做局部最优判断
+贪心算法场景:问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。这种问题
+#回朔:
+能够回退
+#动态规划:
+最优判断 + 回退
+动态规划会保存以前的运算结果,并根据以前的结果的结果对结果对当前进行选择,有回退功能。
+
+#递归
+关注本层的逻辑,在递归前的代码是压栈的时候执行的,递归后代码是出栈时执行的;
+如果压栈前改变全局变量或者参数直,就要考虑出栈时恢复,不然会影响其它子递归;
+必要时画递归树帮助理解。不要尝试像电脑一样每层去调用求解.
+
+DFS 代码模板
+递归状态树的理解:dfs会马上进入到下一层,不用等到for循环,等dfs遇到return才会进入for循环下一个
+```$xslt
+visited = set()
+def dfs(node, visited):
+ if node in visited: # terminator
+ # already visited
+ return
+ visited.add(node)
+ # process current node here.
+ ...
+ for next_node in node.children():
+ if next_node not in visited:
+ dfs(next_node, visited)
+```
+Trivial 非递归写法:
+```
+def DFS(self, tree):
+ if tree.root is None:
+ return []
+ visited, stack = [], [tree.root]
+ while stack:
+ node = stack.pop()
+ visited.add(node)
+ process (node)
+ nodes = generate_related_nodes(node)
+ stack.push(nodes)
+ # other processing work
+ ...
+```
+
+## BFS 代码模板
+```$xslt
+# Python
+def BFS(graph, start, end):
+ visited = set()
+ queue = []
+ queue.append([start])
+ while queue:
+ node = queue.pop()
+ visited.add(node)
+ process(node)
+ nodes = generate_related_nodes(node)
+ queue.push(nodes)
+ # other processing work
+ ...
+
+```
+
+
+#二分查找
+二分查找的前提
+1. 目标函数单调性 (单调递增或递减)
+2. 存在上下界 (bounded)
+3. 能够通过索引访问 (index accessible)
+4. 小心边界值
+```$xslt
+ //用二分查找
+ //1.如果左<右,表示这部分是排序的,另一部分没有排序
+ //2.在排序这部分找,如果target在左右值间,说明target在有序这边
+ //3.否则在无序这边,据继续递归查找
+ public int search(int[] nums, int target) {
+ int mid,left=0;
+ int right=nums.length-1;
+ while (left <= right){
+ mid = left+(right-left)/2;
+ if (nums[mid]==target){
+ return mid;
+ }
+ //有序在前半部分,
+ if (nums[left]<=nums[mid]){
+ //必须考虑左右边界值等于target情况
+ //这里因为right = mid-1;加入target=左边界值
+ if (nums[left]<=target && target a[i-1][0] + nums[i]
+5. DP要夹带更多的信息时,一般就是升维。
+6. 在此基础上考虑重新定义状态数组,降维
+7. 状态数组: a[i]: 0..i天,且nums[i]必偷的最大值, 能偷到max value : max(a)
+8. DP方程 : a[i] = Max(a[i-1], a[i-2] + nums[i]);
+
+```$xslt
+ public int rob(int[] nums) {
+ if (nums == null || nums.length==0) return 0;
+ if (nums.length==1) return nums[0];
+
+ int n = nums.length;
+ int[] dp = new int[n];
+
+ dp[0] = nums[0];
+ dp[1] = Math.max(nums[0],nums[1]);
+
+ for (int i=2;i 2 5
+ / \ / / \
+ 2 3 1 3 6 (3 要换父节点)
+ /
+1
+
+左右旋 (左右子树)
+ 先下面的右子树左旋,变成了左左子树,再做整个子树右旋
+右左旋 (右左子树)
+ 先下面的左子树右旋,变成了右右子树,再做整个子树左旋
+
+## Red-black Tree
+红黑树是一种**近似平衡**的二叉树(Binary Search Tree),
+它能够保证任何一个节点的左右子树**高度差小于两倍**。
+ 1.每个节点要么是红或黑
+ 2.根结点是黑
+ 3.每个叶结点(NIL结点)是黑色的
+ 4.不能有相邻接的两个红节点
+ 5.任何一节点到其每个叶子的所有路径都包含相同数目的黑色结点
+
+ ## AVL Tree vs Red-black Tree
+ 1.AVL trees provide faster lookups than Red Black Trees bacause they are more strictly balanced.
+
+ 2.Red Black Trees provide faster insertion and removal operations than AVL trees as fewer rotations are done due to relatively relaxed balancing.
+
+ 3.AML trees store balance factors or heights with each node, thus requires storeage for an integer pernode whereas Red Black Tree requires only 1 bit of information per node.
+
+ 4.Red Black Trees are used in most of the language libraries, like map, multimap, multisetin C++ whereas AVL trees are used in databases where faster retrievals are required.
diff --git a/.idea/production/algorithm010/Week08/NOTE.md b/.idea/production/algorithm010/Week08/NOTE.md
new file mode 100644
index 000000000..83d3cb7f6
--- /dev/null
+++ b/.idea/production/algorithm010/Week08/NOTE.md
@@ -0,0 +1,180 @@
+学习笔记
+# Sort
+ 1. Compare Sort
+ big O can not smale than O(nlogn).
+ n(logn): heap, mergo, quick
+
+ 2. Non-compare Sort
+ can be O(n)
+
+ https://www.cnblogs.com/onepixel/p/7674659.html
+
+
+# 位运算
+
+### and运算 &
+相同位的两个数字都为1,则为1;若有一个不为1,则为0
+00101
+11100
+&
+------
+00100
+
+### or运算 |
+相同位只要一个为1即为1。
+00101
+11100
+|
+-----
+11101
+
+### 异或运算 ^
+相同位不同则为1,相同则为0。
+00101
+11100
+^
+-----
+11001
+
+### not运算 ~
+not运算的定义是把内存中的0和1全部取反。使用not运算时要格外小心,你需要注意整数类型有没有符号。如果not的对象是无符号整数(不能表示负数),那么得到的值就是它与该类型上界的差,
+
+### shl运算 <<
+a shl b就表示把a转为二进制后左移b位(在后面添b个0),a shl b的值实际上就是a乘以2的b次方
+### shr运算 >>
+a shr b表示二进制右移b位(去掉末b位),相当于a除以2的b次方(取整)。
+
+## 实战位运算要点:
+1. 判断奇偶:
+ x%2==1 -> (x&1)==1
+ x@2==0 -> (x&1)==0
+2. x>>1 -> x/2
+ x=x/2; -> x=x>>1;
+ mid = (left+right)/2; -> mid=(left+right)>>1;
+3. x=x&(x-1) 清零最低位的1
+4. x&-x => 得到最低位的1
+5. x&~x => 0
+
+# 排序
+//https://www.cnblogs.com/onepixel/p/7674659.html
+
+## insertSort
+ 对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
+
+ public int[] insertSort(int[] arr){
+ int len = arr.length;
+ int preIdx, current;
+ for (int i =1;i=0 && arr[preIdx]>current){
+ arr[preIdx+1] = arr[preIdx];
+ preIdx--;
+ }
+ arr[preIdx+1] = current;
+ }
+ return arr;
+ }
+
+## shellSort
+是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。
+
+ public int[] shellSort(int[] arr){
+ int len = arr.length;
+ for (int gap = len/2; gap>0;gap=gap/2){
+ for (int i = gap; i= 0 && current= right) return;
+ int mid = (left+right) >> 1;
+ mergeSort(arr, left, mid);
+ mergeSort(arr, mid+1, right);
+ merge(arr,left,mid,right);
+ }
+
+ private void merge(int[] arr, int left, int mid, int right) {
+ int[] temp = new int[right-left+1];
+ int i = left;
+ int j = mid+1;
+ int k = 0;
+
+ while (i
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 000000000..35eb1ddfb
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 000000000..d0d28e6a2
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,112 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "java",
+ "name": "Debug (Launch) - Current File",
+ "request": "launch",
+ "mainClass": "${file}"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-BinaryHeap",
+ "request": "launch",
+ "mainClass": "Week02.BinaryHeap",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-LC_239_sliding_window_maximum",
+ "request": "launch",
+ "mainClass": "Week02.LC_239_sliding_window_maximum",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-LC_347_top_k_frequent_elements",
+ "request": "launch",
+ "mainClass": "Week02.LC_347_top_k_frequent_elements",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-test",
+ "request": "launch",
+ "mainClass": "Week02.test",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-LC111_min_depth_b_tree",
+ "request": "launch",
+ "mainClass": "Week03.LC111_min_depth_b_tree",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-LC46_permutations",
+ "request": "launch",
+ "mainClass": "Week03.LC46_permutations",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-LC_17_Letter_combinations_of_phone",
+ "request": "launch",
+ "mainClass": "Week03.LC_17_Letter_combinations_of_phone",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-Lc_69_sqrtx",
+ "request": "launch",
+ "mainClass": "Week03.Lc_69_sqrtx",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-Test",
+ "request": "launch",
+ "mainClass": "Week03.Test",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-LC126_word_ladder_ii",
+ "request": "launch",
+ "mainClass": "Week04.LC126_word_ladder_ii",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-LC127_word_ladder",
+ "request": "launch",
+ "mainClass": "Week04.LC127_word_ladder",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-LC153_find_minimum_in_rotated_sorted_array",
+ "request": "launch",
+ "mainClass": "Week04.LC153_find_minimum_in_rotated_sorted_array",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-LC529_minesweeper",
+ "request": "launch",
+ "mainClass": "Week04.LC529_minesweeper",
+ "projectName": "algorithm010_c257f461"
+ },
+ {
+ "type": "java",
+ "name": "Debug (Launch)-test(1)",
+ "request": "launch",
+ "mainClass": "Week04.test",
+ "projectName": "algorithm010_c257f461"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 000000000..2421e386c
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,8 @@
+{
+ "files.exclude": {
+ "**/.classpath": true,
+ "**/.project": true,
+ "**/.settings": true,
+ "**/.factorypath": true
+ }
+}
\ No newline at end of file
diff --git a/AfterGraduation/LC1080_insufficient_nodes.java b/AfterGraduation/LC1080_insufficient_nodes.java
new file mode 100644
index 000000000..fbb066997
--- /dev/null
+++ b/AfterGraduation/LC1080_insufficient_nodes.java
@@ -0,0 +1,72 @@
+package AfterGraduation;
+
+import Common.TreeNode;
+
+public class LC1080_insufficient_nodes {
+/*
+用root.val - limit 带入每层即可在sufficientSubset递归
+ */
+ public TreeNode sufficientSubset(TreeNode root, int limit) {
+
+ if (root == null){
+ return null;
+ }
+ //如果是叶子节点,判断是否需要删去
+ if (root.left==null && root.right==null){
+ if (root.val < limit)
+ return null;
+ else{
+ return root;
+ }
+ }
+ TreeNode left = sufficientSubset(root.left,limit-root.val);
+ TreeNode right = sufficientSubset(root.right,limit-root.val);
+
+ //如果两个子树都被删掉,说明这个节点是不足节点
+ if(left == null && right == null)
+ return null;
+
+ //没被全删点就说明不是不足节点,保留即可
+ root.left = left;
+ root.right = right;
+ return root;
+ }
+
+ /*
+对于二叉树上某一节点的删除,一般有两种做法:
+一种是由其父节点对左右子节点的删除,另一种则是将自身删除。从测试用例3 [5,-6,-6] 的返回结果为 [] 可知,在某些情况下根节点也需要被删除,由于根节点没有父结点,
+因此选择第二种删除方式,为了避免像链表一样出现断链,采用后序遍历,从叶子节点开始删除。
+
+解题思路:不妨设 bool dfs(X, sum, limit) 为判断 root 是否为不足节点的函数,其中 sum 为从根节点 root 到 X 的父结点的路径和,显然若出现以下三种情况,则应当删除:
+1、若 X 的左孩子节点是不足节点,且右孩子也是不足节点,则 X 也是不足节点
+2、若 X 的左孩子节点是不足节点,且右孩子为空,则 X 也是不足节点
+3、若 X 的左孩子为空,且右孩子是不足节点,则 X 也是不足节点
+递归的 Base Case 为:若 X == NULL 则返回 sum < limit
+以下解法错误
+ private boolean dfs_wrong(TreeNode node, int sum, int limit){
+ if (node == null){
+ return sum < limit;
+ }
+ boolean left = dfs(node.left, sum+node.val,limit);
+ //Case 2:
+ if (left && node.right==null){
+ node = null;
+ return true;
+ }
+
+ boolean right = dfs(node.right, sum+node.val,limit);
+ //Case 3:
+ if (right && node.left == null){
+ node = null;
+ return true;
+ }
+ //Case 1;
+ if (left && right){
+ node = null;
+ return true;
+ }
+ return left && right;
+ }
+
+ */
+}
diff --git a/Common/BuildBinaryTree.java b/Common/BuildBinaryTree.java
new file mode 100644
index 000000000..ef7e15af5
--- /dev/null
+++ b/Common/BuildBinaryTree.java
@@ -0,0 +1,81 @@
+package Common;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+public class BuildBinaryTree {
+
+ // PriorityQueue
+ // Deque -> Stack
+
+ public static TreeNode buildBinaryTree(Integer[] list) {
+
+ if(list == null || list.length == 0) return null;
+ Queue queue = new LinkedList<>();
+ TreeNode root = new TreeNode(list[0]);
+ int j =1;
+ int length = list.length;
+ queue.add(root);
+ while(!queue.isEmpty() && j< length){
+
+ TreeNode curNode = queue.poll();
+ if (list[j] != null){
+ curNode.left = new TreeNode(list[j]);
+ queue.add(curNode.left);
+ }
+ j++;
+ if (j ==length){break;}
+
+ if (list[j] != null) {
+ curNode.right = new TreeNode(list[j]);
+ queue.add(curNode.right);
+ }
+ j++;
+ }
+ return root;
+ }
+
+ public TreeNode build(Integer[] list){
+ if(list.length == 0) return null;
+ Queue queue = new LinkedList<>();
+
+ TreeNode root = new TreeNode(list[0]);
+
+ queue.add(root);
+ int lineNum =2;
+ int startIndex =1;
+ int restLength = list.length-1;
+
+ while(restLength >0){
+ for (int index = startIndex;index < startIndex + lineNum; index=index+2){
+ if (index == list.length){
+ return root;
+ }
+ TreeNode curNode = queue.poll();
+ if (list[index] != null)
+ {
+ if(curNode!=null) {
+ curNode.left = new TreeNode(list[index]);
+ queue.add(curNode.left);
+ }
+ }
+
+ if (index+1 == list.length)
+ return root;
+
+ if (list[index+1] != null)
+ {
+ if(curNode!=null){
+ curNode.right = new TreeNode(list[index+1]);
+ queue.add(curNode.right);
+ }
+ }
+ }
+ startIndex +=lineNum;
+ restLength -=lineNum;
+ lineNum = queue.size() * 2;
+ }
+ return root;
+ }
+
+}
diff --git a/Common/TreeNode.java b/Common/TreeNode.java
new file mode 100644
index 000000000..28fe9f26c
--- /dev/null
+++ b/Common/TreeNode.java
@@ -0,0 +1,14 @@
+package Common;
+
+public class TreeNode {
+ public int val;
+ public TreeNode left;
+ public TreeNode right;
+ public TreeNode() {}
+ public TreeNode(int val) { this.val = val; }
+ public TreeNode(int val, TreeNode left, TreeNode right) {
+ this.val = val;
+ this.left = left;
+ this.right = right;
+ }
+}
diff --git a/DesignPattern/DesignPattern-ResponseTimeMetrics/api-analysis/.idea/workspace.xml b/DesignPattern/DesignPattern-ResponseTimeMetrics/api-analysis/.idea/workspace.xml
new file mode 100644
index 000000000..3d52f630b
--- /dev/null
+++ b/DesignPattern/DesignPattern-ResponseTimeMetrics/api-analysis/.idea/workspace.xml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1598028393235
+
+
+ 1598028393235
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Interview/CAPCO.java b/Interview/CAPCO.java
new file mode 100644
index 000000000..f5a01d9ca
--- /dev/null
+++ b/Interview/CAPCO.java
@@ -0,0 +1,66 @@
+package Interview;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class CAPCO {
+ public static void main(String[] args) {
+
+ if ("s" instanceof String)
+
+ System.out.println(1);
+ }
+
+ public static String uniqueString_1(List words) {
+
+ LinkedHashMap map = new LinkedHashMap<>(words.size());
+
+ for (String s : words) {
+ Integer count = map.getOrDefault(s, 0);
+ map.put(s, count + 1);
+ }
+
+ for (Map.Entry entry : map.entrySet()) {
+ if (entry.getValue() == 1) {
+ return entry.getKey();
+ }
+ }
+
+ return "";
+ }
+
+ public static String uniqueString_2(List words) {
+ Map stringCountMap = words.stream()
+ .collect(Collectors.groupingBy(s -> s, LinkedHashMap::new, Collectors.counting()));
+ for (String s : stringCountMap.keySet()) {
+ if (stringCountMap.get(s) == 1) {
+ return s;
+ }
+ }
+ return "";
+ }
+
+ public static String uniqueString(List words) {
+// return words.stream()
+// .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
+// .entrySet()
+// .stream()
+// .filter(entry -> entry.getValue() == 1)
+// .findFirst()
+// .map(Map.Entry::getKey)
+// .orElse(null);
+
+ StringBuilder result = new StringBuilder();
+ words.stream()
+ .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
+ .entrySet()
+ .stream()
+ .filter(entry -> entry.getValue() == 1)
+ .findFirst()
+ .ifPresent(entry -> result.append(entry.getKey()));
+ return result.toString();
+ }
+
+}
diff --git a/Interview/HSBC.java b/Interview/HSBC.java
new file mode 100644
index 000000000..6ac5ba606
--- /dev/null
+++ b/Interview/HSBC.java
@@ -0,0 +1,38 @@
+package Interview;
+
+import Common.BuildBinaryTree;
+import Common.TreeNode;
+
+public class HSBC {
+
+ public static void swap(int a, int b){
+// a = (a+b)-(b=a);
+
+ a=a+b;
+ b=a-b;
+ a=a-b;
+
+ System.out.println("a="+a+"; b="+b);
+ }
+
+
+ public static int sumOfBinaryTree(TreeNode root){
+ if (root==null){
+ return 0;
+ }
+ return sumOfBinaryTree(root.left)+ sumOfBinaryTree(root.right)+root.val;
+ }
+
+
+ public static void main(String[] args) {
+
+ int a=1, b=2;
+ swap(a,b);
+
+// System.out.println("a="+a+"; b="+b);
+// Integer[] list = new Integer[]{1,2,3,null,null,4};
+// TreeNode root = BuildBinaryTree.buildBinaryTree(list);
+// sumOfBinaryTree(root);
+// System.out.println("Sum="+ sumOfBinaryTree(root));
+ }
+}
diff --git a/Interview/Rogers.java b/Interview/Rogers.java
new file mode 100644
index 000000000..ae7037705
--- /dev/null
+++ b/Interview/Rogers.java
@@ -0,0 +1,104 @@
+package Interview;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class Rogers {
+
+ Map count(Map... visits) {
+ Map res = new HashMap<>();
+ if (visits == null ) return res;
+ for(Map m : visits){
+ if (m!=null){
+ for(String mkey : m.keySet()){
+ try{
+ Long id = Long.parseLong(mkey);
+ UserStats uStats = m.get(mkey);
+ if (uStats !=null){
+ Optional value = uStats.getVisitCount();
+ if (value!=null && value.isPresent()){
+ Long vistCount = value.get();
+ if (res.containsKey(id)){
+ vistCount = vistCount + res.get(id);
+ }
+ res.put(id,vistCount);
+ }
+ }
+ }catch (NumberFormatException e){
+ //ignore
+ }
+ }
+ }
+ }
+
+ return res;
+ }
+
+
+ Map count2(Map... visits) {
+ Map res = new HashMap<>();
+ if (visits == null ) return res;
+ for(Map m : visits) {
+ if (m != null) {
+ m.entrySet()
+ .stream()
+ .filter(entry -> isValid(entry.getKey(),entry.getValue()))
+ .forEach((entry) -> {
+ Long id = Long.valueOf(entry.getKey()) ;
+ Long vistCount = entry.getValue().getVisitCount().get();
+ res.put(id,vistCount+ res.getOrDefault(id, new Long(0)));
+ });
+ }
+ }
+ return res;
+ }
+
+ boolean isValid(String key, UserStats value){
+ if (key==null || value == null || !isLong(key)){
+ return false;
+ }
+ if (value.getVisitCount() == null || !value.getVisitCount().isPresent())
+ return false;
+ return true;
+ }
+ boolean isLong(String s){
+ try{
+ Long.parseLong(s);
+ return true;
+ }catch (NumberFormatException e){
+ //ignore
+ }
+ return false;
+ }
+}
+
+class test {
+
+ public static void main(String[] args) {
+ Map visitStats1 = new HashMap<>();
+ visitStats1.put("123", new UserStats(Optional.of(new Long(2))));
+ visitStats1.put("456", new UserStats(null));
+ visitStats1.put(null, null);
+ visitStats1.put("444", null);
+
+ visitStats1.put("567", new UserStats(Optional.empty()));
+
+ visitStats1.put("234", new UserStats(Optional.of(new Long(1))));
+
+ Map visitStats2 = new HashMap<>();
+ Optional count2 = Optional.of(new Long(3));
+ visitStats2.put("123", new UserStats(count2));
+
+ Rogers rogers = new Rogers();
+ Map res = rogers.count2(visitStats1,visitStats2,null);
+
+// Map res = rogers.count(null);
+ res.forEach((K,V)->{
+ System.out.println("Key:"+K+"; Value:"+V);
+ });
+ }
+}
+
+
diff --git a/Interview/UserStats.java b/Interview/UserStats.java
new file mode 100644
index 000000000..d6c20b21f
--- /dev/null
+++ b/Interview/UserStats.java
@@ -0,0 +1,14 @@
+package Interview;
+
+import java.util.Optional;
+
+public class UserStats {
+ Optional visitCount;
+
+ public UserStats(Optional count){
+ this.visitCount = count;
+ }
+ public Optional getVisitCount(){
+ return visitCount;
+ }
+}
diff --git a/October2020/LC496_next_greater_element_i.java b/October2020/LC496_next_greater_element_i.java
new file mode 100644
index 000000000..14900bff1
--- /dev/null
+++ b/October2020/LC496_next_greater_element_i.java
@@ -0,0 +1,26 @@
+package October2020;
+
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+public class LC496_next_greater_element_i {
+
+ public int[] nextGreaterElement(int[] nums1, int[] nums2) {
+ Map map = new HashMap();
+ Deque stack = new LinkedList();
+ for (int i=0; i stack = new LinkedList<>();
+ int n = nums.length;
+ for (int i=2*n-1;i>=0;i--){
+ while(!stack.isEmpty() && stack.peek()<=nums[i%n]){
+ stack.pop();
+ }
+ ans[i%n] = stack.isEmpty() ? -1 : stack.peek();
+ stack.push(nums[i%n]);
+ }
+ return ans;
+ }
+
+ public static void main(String[] args) {
+ int[] nums = {1,2,1};
+ int[] ans = nextGreaterElements(nums);
+
+ Arrays.stream(ans).forEach(a->System.out.println(a));
+ }
+}
diff --git a/Summayr.md b/Summayr.md
new file mode 100644
index 000000000..4a9e6c9d5
--- /dev/null
+++ b/Summayr.md
@@ -0,0 +1,8 @@
+# **学习总结**
+###### 经过70 天的学习,主要有如下方面的收获。
+
+切题四件套、五毒神掌等一定要牢记,不能偷懒。算法只有进行时,没有完成时,一定要多练,而且每题要重复边数。
+
+解题80+,开始比较认真,后面松懈了,最近两周没上leetcode.好多居然都不会写了。>^<
+
+最后,在此感谢老师、助教、班主任的辛勤付出和同学们的互相帮助。
\ No newline at end of file
diff --git a/Week01/LC189_rotate-array.md b/Week01/LC189_rotate-array.md
new file mode 100644
index 000000000..ec7ca573f
--- /dev/null
+++ b/Week01/LC189_rotate-array.md
@@ -0,0 +1,17 @@
+
+class Solution {
+
+ //Brute-force
+ //move k times for all elements - O(k^n)
+
+ public void rotate(int[] nums, int k) {
+ int length = nums.length;
+ for(int i=0;i0;j--){
+ nums[j] = nums[j-1];
+ }
+ nums[0] = tmp;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Week01/LC206_ReverseLinkedList.md b/Week01/LC206_ReverseLinkedList.md
new file mode 100644
index 000000000..cc4945ef8
--- /dev/null
+++ b/Week01/LC206_ReverseLinkedList.md
@@ -0,0 +1,104 @@
+/*
+第一次写道这样就试着运行,链表和Recursive不清楚 :-)
+*/
+class Solution {
+
+ ListNode res = new ListNode();
+
+ public ListNode reverseList(ListNode head) {
+
+ if (head == null){
+ return null;
+ }
+
+ res.next = head;
+ res = res.next;
+
+ return reverseList(head.next);
+ }
+
+}
+
+//因为要达到末尾时才能够进行连接,所以要在出栈的时候(recursive 调用后)
+class Solution {
+
+ ListNode res = new ListNode();
+
+ public ListNode reverseList(ListNode head) {
+ helper(head);
+ return res;
+ }
+ private ListNode helper(ListNode node){
+ if(node == null || node.next == null){
+ res = node;
+ return node;
+ }
+ ListNode temp = helper(node.next);
+ temp.next = node;
+ node.next = null;
+ return node;
+ }
+}
+
+/*看完题解后:
+1. 迭代法: 用 prev, curr, head 反转指针
+prev = head;
+curr = head.next;
+curr.next = prev; //反转指针
+head = curr;
+
+定义两个指针: pre 和 cur ;pre 在前 cur 在后。
+每次让 pre 的 next 指向 cur ,实现一次局部反转
+局部反转完成之后,pre 和 cur 同时往前移动一个位置
+循环上述过程,直至 pre 到达链表尾部
+
+*/
+class Solution {
+ public ListNode reverseList(ListNode head) {
+ ListNode cur = null, pre=head;
+ while(pre!=null){
+ ListNode tmp = pre.next;
+ pre.next = cur;
+ cur = pre;
+ pre = tmp;
+ }
+ return cur;
+ }
+ //时间复杂度:O(n)O(n)
+ //空间复杂度:O(1)O(1)
+}
+
+/* 2.递归
+递归就是压栈,在递归调用前的code就是压栈前要执行的,在递归调用后的code就是出栈后执行的。
+有没有一种方法/公式,知道是这段代码是放在递归前还是递归后
+ */
+class Solution {
+ public ListNode reverseList(ListNode head) {
+ //terminator
+ if(head == null || head.next == null){
+ return head;
+ }
+ ListNode node = reverseList(head.next); //这里会一直迭代直到触发terminator(走到链表最后),然后才执行下面语句
+ head.next.next = head;
+ head.next = null; //这里是为了断开连接
+ return node;
+ }
+}
+
+/* 递归 2
+ return helper(nextNode, curr); //用value互换来达到指针反转
+ */
+class Solution {
+ public ListNode reverseList(ListNode head) {
+ return helper(head, null);
+ }
+
+ private ListNode helper(ListNode curr, ListNode newList){
+ if (curr == null){
+ return newList;
+ }
+ ListNode nextNode = curr.next;
+ curr.next = newList;
+ return helper(nextNode, curr); //用参数互换来达到指针反转
+ }
+}
\ No newline at end of file
diff --git a/Week01/LC21_merge-two-sorted-lists.md b/Week01/LC21_merge-two-sorted-lists.md
new file mode 100644
index 000000000..a84347b6d
--- /dev/null
+++ b/Week01/LC21_merge-two-sorted-lists.md
@@ -0,0 +1,30 @@
+
+class Solution {
+
+ /*
+ 思路
+
+ 终止条件:两条链表分别名为 l1 和 l2,当 l1 为空或 l2 为空时结束
+ 返回值:每一层调用都返回排序好的链表头
+ 本级递归内容:如果 l1 的 val 值更小,则将 l1.next 与排序好的链表头相接,l2 同理
+ O(m+n)O(m+n),mm 为 l1的长度,nn 为 l2 的长度
+ */
+
+ public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
+ //terminator:
+ if(l1 == null){
+ return l2;
+ }
+ if(l2 == null){
+ return l1;
+ }
+ if (l1.val < l2.val){
+ l1.next = mergeTwoLists(l1.next, l2);
+ return l1;
+ }
+ else {
+ l2.next = mergeTwoLists(l1, l2.next);
+ return l2;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Week01/LC26_remove-duplicates-from-sorted-array.md b/Week01/LC26_remove-duplicates-from-sorted-array.md
new file mode 100644
index 000000000..7c440b78b
--- /dev/null
+++ b/Week01/LC26_remove-duplicates-from-sorted-array.md
@@ -0,0 +1,21 @@
+
+class Solution {
+
+
+ //代替法,用j保存修改数组的位置
+
+ public int removeDuplicates(int[] nums) {
+ if (nums == null || nums.length==0){
+ return 0;
+ }
+ int j =0;
+ for(int i=0;i=0) {
+ // when nums1 reach the head, p1 will become -1
+ if (p1 == -1 || nums1[p1] <= nums2[p2]) {
+ nums1[p] = nums2[p2];
+ p2--;
+ }
+ else{
+ nums1[p] = nums1[p1];
+ p1--;
+ }
+ p--;
+
+ nums1[p--] = (p1 == -1 || nums1[p1] <= nums2[p2]) ? nums2[p2--] : nums1[p1--];
+ }
+ }
+}
+
+//可以简化成四行
+class Solution {
+ public void merge(int[] nums1, int m, int[] nums2, int n) {
+ int p1 = m - 1, p2 = n - 1, p = m + n - 1;
+ while (p2 >= 0) {
+ nums1[p--] = (p1 == -1 || nums1[p1] <= nums2[p2]) ? nums2[p2--] : nums1[p1--];
+ }
+ }
+}
\ No newline at end of file
diff --git a/Week01/LC_283_MoveZeroes.md b/Week01/LC_283_MoveZeroes.md
new file mode 100644
index 000000000..500ef6dbb
--- /dev/null
+++ b/Week01/LC_283_MoveZeroes.md
@@ -0,0 +1,47 @@
+class Solution {
+
+
+ public void moveZeroes(int[] nums) {
+ //把0用后面的数代替,并统计0的个数记录在j上
+ int j =0;
+ for(int i=0;i=0;i--){
+ digits[i]++;
+ digits[i] = digits[i] % 10;
+ //e.g. 1,9,9; when it becomes 200. it will end th loop
+ if (digits[i] != 0) return digits;
+ }
+ // reach here, only when all digits are 9. e.g. 999
+ // in java, int[] initia with '0'
+ int[] newDigits = new int[digits.length +1];
+ // System.arraycopy(digits,0,newDigits,1,digits.length);
+ newDigits[0] = 1;
+ return newDigits;
+
+ }
+}
\ No newline at end of file
diff --git a/Week01/LeetCode_11.md b/Week01/LeetCode_11.md
new file mode 100644
index 000000000..96824c7e6
--- /dev/null
+++ b/Week01/LeetCode_11.md
@@ -0,0 +1,27 @@
+class Solution {
+
+
+ //11. 盛最多水的容器
+
+ public int maxArea(int[] height) {
+
+ int len = height.length;
+ int i=0, j=len-1,h=0;
+ int maxArea =0;
+
+ while (i> threeSum(int[] nums) {
+ List> result = new ArrayList<>();
+ int len = nums.length;
+ if (nums == null || len<3) {
+ return result;
+ }
+ //sort是关键,排序完就很容易去重了
+ Arrays.sort(nums);
+
+ for (int i=0;i0 && nums[i] == nums[i-1]) continue;
+ //用while一样效果,不用回到for去判断
+ while (i>0 && i0) break;
+
+ int left = i+1;
+ int right = len-1;
+ while (left stack = new LinkedList();
+ stack.addFirst("a");
+ stack.addFirst("b");
+ stack.addFirst("c");
+ System.out.println(stack);
+
+ String str = stack.peek();
+ System.out.println(str);
+ System.out.println(stack);
+ while (stack.size()>0){
+ System.out.println(stack.removeFirst());
+ }
+ System.out.println(stack);
+
diff --git a/Week02/Amazon_Interview_Q1.java b/Week02/Amazon_Interview_Q1.java
new file mode 100644
index 000000000..4bdc9d46a
--- /dev/null
+++ b/Week02/Amazon_Interview_Q1.java
@@ -0,0 +1,122 @@
+package Week02;
+
+import java.util.*;
+
+public class Amazon_Interview_Q1 {
+
+ class Trie {
+
+ Trie[] children = new Trie[100];
+ boolean isEnd;
+ String value;
+
+ /** Initialize your data structure here. */
+ public Trie() {
+
+ }
+
+ /** Inserts a word into the trie. */
+ public void insert(String word) {
+ Trie tmp = this;
+ for(char c: word.toCharArray()){
+ if (tmp.children[c-'a']==null){
+ tmp.children[c-'a'] = new Trie();
+ }
+ tmp = tmp.children[c-'a'];
+ }
+ tmp.isEnd = true;
+ tmp.value = word;
+ }
+
+ public boolean search(String word) {
+ Trie tmp = this;
+
+ for(char c: word.toCharArray()){
+ if (tmp.children[c-'a'] == null){
+ return false;
+ }
+ tmp = tmp.children[c-'a'];
+ }
+ return tmp.isEnd;
+ }
+
+ }
+
+ private HashSet searchReview( Trie cmptTrie, String review){
+ Trie tmp = cmptTrie;
+ HashSet cmptSet = new HashSet<>();
+ for(char c: review.toCharArray()){
+ if(c == ' '){
+ continue;
+ }
+ if (tmp.children[c-'a'] == null){
+ tmp = cmptTrie;
+ }
+ else if(tmp.isEnd){
+ cmptSet.add(tmp.value);
+ tmp = cmptTrie;
+ }
+ else {
+ tmp = tmp.children[c-'a'];
+ }
+ }
+ return cmptSet;
+ }
+
+
+ public List finTopNcompetitors(int numCompetitors, int topNCompetitors,
+ Listcompentitors, int numReviews, Listreviews){
+
+ Trie cmptTrie = new Trie();
+ for (String cpts: compentitors){
+ cmptTrie.insert(cpts.toLowerCase());
+ }
+ HashMap cmpMap = new HashMap<>();
+
+ PriorityQueue> pq = new PriorityQueue<>(
+ (a,b) -> a.getValue()==b.getValue() ? b.getKey().compareTo(a.getKey()) : a.getValue()-b.getValue()
+ );
+
+ for (String review: reviews){
+ HashSet cmptSet = searchReview(cmptTrie,review.toLowerCase());
+ for (String s: cmptSet){
+ cmpMap.put(s,cmpMap.getOrDefault(s,0)+1);
+ }
+ }
+
+ for(Map.Entry entry: cmpMap.entrySet())
+ {
+ pq.offer(entry);
+ if(pq.size()>numReviews)
+ pq.poll();
+ }
+
+ List result = new ArrayList<>();
+ while(!pq.isEmpty())
+ result.add(0, pq.poll().getKey());
+
+ return result;
+ }
+}
+
+
+class Amazon_Interview_Q1_test {
+ public static void main(String[] args) {
+ Amazon_Interview_Q1 solution = new Amazon_Interview_Q1();
+ int numCompetitors=5;
+ int topNCompetitors=2;
+ Listcompentitors = Arrays.asList("anacell",
+ "betacellular",
+ "cetracular",
+ "deltacellular",
+ "eurocell");
+ int numReviews =3;
+ List reviews= Arrays.asList("best services provided by anacell",
+ "betacellular has great services",
+ "anacell provides much better services than all other");
+
+ List result = solution.finTopNcompetitors( numCompetitors, topNCompetitors,
+ compentitors, numReviews, reviews);
+
+ }
+}
diff --git a/Week02/Amazon_Interview_Q2.java b/Week02/Amazon_Interview_Q2.java
new file mode 100644
index 000000000..4a5f6c096
--- /dev/null
+++ b/Week02/Amazon_Interview_Q2.java
@@ -0,0 +1,138 @@
+package Week02;
+
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.LinkedList;
+
+public class Amazon_Interview_Q2 {
+
+ //找到'0', 然后看前后左右要几次迭代才能发现'1'.
+ //记录所有这些次数,return 最大值
+ int nr,nc;
+ int ans = -1;
+ HashMap map = new HashMap();
+ public int daysOfUpdate(int rows, int columns, char[][] grid) {
+ if (rows <=0 || columns<=0) {
+ return ans;
+ }
+
+ nr = rows;
+ nc = columns;
+// LinkedList list = new LinkedList<>();
+
+ for (int i=0;i 0 && insertValue > heap[parent(i)]) {
+ heap[i] = heap[parent(i)];
+ i = parent(i);
+ }
+ heap[i] = insertValue;
+ }
+
+
+ /**
+ * Maintains the heap property while deleting an element.
+ */
+ private void heapifyDown(int i) {
+ int child;
+ int temp = heap[i];
+ while (kthChild(i, 1) < heapSize) {
+ child = maxChild(i);
+ if (temp >= heap[child]) {
+ break;
+ }
+ heap[i] = heap[child];
+ i = child;
+ }
+ heap[i] = temp;
+ }
+
+
+ private int maxChild(int i) {
+ int leftChild = kthChild(i, 1);
+ int rightChild = kthChild(i, 2);
+ return heap[leftChild] > heap[rightChild] ? leftChild : rightChild;
+ }
+
+
+ /**
+ * Prints all elements of the heap
+ */
+ public void printHeap() {
+ System.out.print("nHeap = ");
+ for (int i = 0; i < heapSize; i++)
+ System.out.print(heap[i] + " ");
+ System.out.println();
+ }
+
+
+ /**
+ * This method returns the max element of the heap.
+ * complexity: O(1)
+ */
+ public int findMax() {
+ if (isEmpty())
+ throw new NoSuchElementException("Heap is empty.");
+ return heap[0];
+ }
+
+
+ public static void main(String[] args) {
+ BinaryHeap maxHeap = new BinaryHeap(10);
+ maxHeap.insert(10);
+ maxHeap.insert(4);
+ maxHeap.insert(9);
+ maxHeap.insert(1);
+ maxHeap.insert(7);
+ maxHeap.insert(5);
+ maxHeap.insert(3);
+
+
+ maxHeap.printHeap();
+ maxHeap.delete(5);
+ maxHeap.printHeap();
+ maxHeap.delete(2);
+ maxHeap.printHeap();
+ }
+}
+
diff --git "a/Week02/HashMap\346\200\273\347\273\223.md" "b/Week02/HashMap\346\200\273\347\273\223.md"
new file mode 100644
index 000000000..465cb6d27
--- /dev/null
+++ "b/Week02/HashMap\346\200\273\347\273\223.md"
@@ -0,0 +1,161 @@
+一,HashMap的内部存储结构
+
+Java中数据存储方式最底层的两种结构,一种是数组,另一种就是链表。
+
+数组的特点:连续空间,寻址迅速,但是在删除或者添加元素的时候需要有较大幅度的移动,所以查询速度快,增删较慢。
+链表的特点:由于空间不连续,寻址困难,增删元素只需修改指针,所以查询慢、增删快。
+综合这两者的优点,摒弃缺点,哈希表就诞生了,既满足了数据查找方面的特点,占用的空间也不大。
+
+二、底层原理
+
+HashMap的实现主要用到了哈希表的链地址法。即使用数组+链表的方式实现。
+hashMap实现了Map接口,继承了AbstractMap类。其中Map接口定义了键映射到值的规则,AbstractMap类提供了Map接口的骨干实现。
+hashMap底层有一个entry数组(entry是hashMap的内部类,它包含了键key、值value、下一个节点next,以及hash值,
+正是由于Entry才构成了table数组的项为链表),数组上每一项都有一个链表,如果链表长度超过阀值( TREEIFY THRESHOLD==8),就把链表转成红黑树,链表长度低于6,就把红黑树转回链表
+
+JDK 1.7 有源码分析
+三、HashMap提供的三个构造函数:
+
+1、HashMap():
+构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
+
+2、HashMap(int initialCapacity):
+构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
+
+3、HashMap(int initialCapacity, float loadFactor):
+构造一个带指定初始容量和加载因子的空 HashMap。
+
+常量
+static final int DEFAULT_INITIAL_CAPACITY = 16;
+初始容量:16
+static final int MAXIMUM_CAPACITY = 1 << 30;
+最大容量:2的30次方 => 1073741824
+static final float DEFAULT_LOAD_FACTOR = 0.75f;
+负载因子:75%
+
+** put(Object key,Object value)方法:
+
+作用是存储一个键-值对
+
+ public V put(K key, V value) {
+ if (key == null)
+ return putForNullKey(value);
+ int hash = hash(key.hashCode());
+ int i = indexFor(hash, table.length);
+ for (Entry e = table[i]; e != null; e = e.next) {
+ Object k;
+ if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
+ V oldValue = e.value;
+ e.value = value;
+ e.recordAccess(this);
+ return oldValue;
+ }
+ }
+
+ modCount++;
+ addEntry(hash, key, value, i);
+ return null;
+ }
+
+ 处理步骤如下:
+ (1)判断key是否为null,若为null,调用putForNullKey(value)处理。这个方法代码如下:
+
+ /**
+ * Offloaded version of put for null keys
+ */
+ private V putForNullKey(V value) {
+ for (Entry e = table[0]; e != null; e = e.next) {
+ if (e.key == null) {
+ V oldValue = e.value;
+ e.value = value;
+ e.recordAccess(this);
+ return oldValue;
+ }
+ }
+ modCount++;
+ addEntry(0, null, value, 0);
+ return null;
+ }
+
+
+从代码可以看出,如果key为null的值,默认就存储到table[0]开头的链表了。然后遍历table[0]的链表的每个节点Entry,
+如果发现其中存在节点Entry的key为null,就替换新的value,然后返回旧的value,
+如果没发现key等于null的节点Entry,就增加新的节点。
+
+(2)先计算key的hashcode,在使用计算的结果二次hash,使用indexFor(hash, table.length)方法找到Entry数组的索引i的位置。
+
+(3)接着遍历以table[i]为头结点的链表,如果发现已经存在节点的hash、key值与条件相同时,
+将该节点的value值替换为新的value值,然后返回旧的value值。
+
+(4)如果未找到hash、key值均相同的节点,则调用addEntry方法增加新的节点(头插法)。代码如下:
+
+ void addEntry(int hash, K key, V value, int bucketIndex) {
+ Entry e = table[bucketIndex];
+ table[bucketIndex] = new Entry(hash, key, value, e);
+ if (size++ >= threshold)
+ resize(2 * table.length);
+ }
+
+
+**get(Object key)方法:
+
+作用是根据键来获取值
+
+ public V get(Object key) {
+ if (key == null)
+ return getForNullKey();
+ int hash = hash(key.hashCode());
+ for (Entry e = table[indexFor(hash, table.length)];
+ e != null;
+ e = e.next) {
+ Object k;
+ if (e.hash == hash && ((k = e.key) == key || key.equals(k)))//-------------------1----------------
+ return e.value;
+ }
+ return null;
+ }
+
+
+处理步骤如下:
+(1)当key为null时,调用getForNullKey(),它的源码如下:
+
+ private V getForNullKey() {
+ for (Entry e = table[0]; e != null; e = e.next) {
+ if (e.key == null)
+ return e.value;
+ }
+ return null;
+ }
+
+返回table[0]开头的链表的键为null的节点的值
+
+(2)当键不为null时,依然计算hash值,然后找到具体在哪个table[indexFor(hash, table.length)]
+节点开头的链表中,遍历此链表查找是否存在搜索条件中的key值,返回其value。若没有符合条件的key值,返回null。
+
+
+***HashMap常考问题总结
+
+最后补充一些面试时候常问到的一些问题总结。
+
+(1)HashMap和HashTable的区别?
+
+HashMap是非线程安全的,HashTable是线程安全的
+HashMap的键和值都允许有null值存在,而HashTable则不行
+因为线程安全的问题,HashMap效率比HashTable的要高
+哈希值的使用不同,HashMap要根据hashCode二次计算得到hash值,而HashTable直接使用对象的hashCode
+继承的父类不同,HashMap继承自AbstractMap,而HashTable继承自Dictionary
+
+(2)HashMap中的键可以是任何对象或数据类型吗?
+
+可以为null,但是不能为可变对象。如果为可变对象的话,对象中的属性改变则对象的hashCode也进行了相应的改变,导致下次无法查找到已存在Map中的数据。
+如果可变对象在HashMap中被当做键,那么就要小心在它的属性改变时,不要改变它的hashCode。只要保证成员变量的改变不会相应改变其hashCode即可。
+
+(3)HashTable如何实现线程安全?
+
+实现原理是在对应的方法上添加了synchronized关键字进行修饰,由于在执行此方法时需要获得对象锁,
+因此执行起来比较慢。如果想实现线程安全的HashMap的话,推荐使用ConcurrentHashMap。
+
+
+参考资料:
+链接:https://www.jianshu.com/p/2f50d21dbfdc
+
diff --git a/Week02/LC_200_number_of_islands.java b/Week02/LC_200_number_of_islands.java
new file mode 100644
index 000000000..5e337c515
--- /dev/null
+++ b/Week02/LC_200_number_of_islands.java
@@ -0,0 +1,99 @@
+package Week02;
+
+import java.util.Deque;
+import java.util.LinkedList;
+
+public class LC_200_number_of_islands {
+/*
+* 「陆地沉没方法」,即遍历完一个陆地格子就让陆地「沉没」为海洋。
+* 这种方法看似很巧妙,但实际上有很大隐患,因为这样我们就无法区分「海洋格子」和「已遍历过的陆地格子」了。
+* 如果题目更复杂一点,这很容易出 bug。
+* */
+ public int numIslands(char[][] grid) {
+ if (grid == null || grid.length ==0 ){
+ return 0;
+ }
+ int nr = grid.length;
+ int nc = grid[0].length;
+ int ans = 0;
+ for (int i=0;i queue = new LinkedList<>();
+ // 用一个数保存两个数字!!(因为c0 && grid[x-1][y] == '1'){
+ //search deeper
+ queue.addFirst((x-1)*nc+y);
+ grid[x-1][y] = '0';
+ }
+ if(x0 && grid[x][y-1] == '1'){//left
+ queue.addFirst(x*nc+y-1);
+ grid[x][y-1] = '0';
+ }
+ if(ynums[pivot]){
+ swap(nums,i,count++);
+ }
+ }
+ swap(nums,count,pivot);
+ return count;
+ }
+ private void swap(int[] nums, int i, int j){
+ if (nums[i]!= nums[j]){
+ nums[i] = nums[i] + nums[j] - (nums[j] = nums[i]);
+ }
+ }
+}
diff --git a/Week02/LC_22_generate_parentheses.java b/Week02/LC_22_generate_parentheses.java
new file mode 100644
index 000000000..2ea007d41
--- /dev/null
+++ b/Week02/LC_22_generate_parentheses.java
@@ -0,0 +1,140 @@
+package Week02;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.PriorityQueue;
+import java.util.Stack;
+
+public class LC_22_generate_parentheses {
+
+ public List generateParenthesis_new(int n){
+ List res = new ArrayList<>();
+ if (n<=0){
+ return res;
+ }
+ StringBuilder sb = new StringBuilder();
+ generate(res,0,0,sb ,n);
+ return res;
+ }
+
+ private void generate(List res, int l, int r, StringBuilder s, int n) {
+ if (l==r && l == n){
+ res.add(s.toString());
+ return;
+ }
+ if (l generateParenthesis(int n) {
+ List res = new ArrayList<>();
+
+ useStringBuilder(0,0,n,new StringBuilder(),res);
+ // generate(0,0,n,"", res);
+ // useStack(n,res);
+ return res;
+ }
+
+ private void useStringBuilder(int left, int right, int n, StringBuilder sb, List res){
+
+ //terminator
+ if(left ==right && left == n){
+ System.out.println(sb.toString());
+ res.add(sb.toString());
+
+ }
+ //process current logic;
+ if (left res){
+ Stack stack = new Stack<>();
+
+ stack.add(new Node(0, 0,""));
+
+ while(!stack.empty()){
+ Node curr = stack.pop();
+ if(curr.leftcurr.right){
+ stack.push(new Node(curr.left, curr.right+1,curr.val+")"));
+ }
+
+ if (curr.left == n && curr.right==n) {
+ System.out.println(curr.val);
+ res.add(curr.val);
+ }
+ }
+ }
+
+ class Node{
+ int left;
+ int right;
+ String val;
+ public Node(int l,int r, String s){
+ left = l;
+ right = r;
+ val = s;
+ }
+ }
+ // Recursion
+ private void generate(int left, int right, int n, String sb, List res) {
+ System.out.println("left = "+left);
+ //terminator
+ if(left ==right && left == n){
+ System.out.println(sb.toString());
+ res.add(sb.toString());
+
+ }
+ //process curren logic;
+ if (left queue = new ArrayDeque<>();
+
+ while (hi < len) {
+ if (hi - lo < k) {
+ addQueue(queue, nums, hi);
+ hi++;
+ } else {
+ ans[lo] = nums[queue.getFirst()];
+ //queue顶元素是窗口的最后一个值,queue从queue中移除顶元素
+ if (queue.getFirst() == lo) {
+ queue.removeFirst();
+ }
+ lo++;
+ }
+ }
+ //only last k of elements in queue, we need to get the max value
+ ans[lo] = nums[queue.getFirst()];
+ return ans;
+ }
+
+ // monotonous queue
+ //queue 只存数组下标,每次进queue,从后比较其他下标的值,如果比它小,扔掉。最后加入该下标。
+ //queue 允许超过k个元素,因为我们只关心最大值
+ private void addQueue(Deque q, int[] nums, int hi) {
+ while (!q.isEmpty() && nums[q.getLast()] < nums[hi]) {
+ q.removeLast();
+ }
+ q.addLast(hi);
+ }
+
+//----------------------test-------------//
+ public static void main(String[] args) {
+ LC_239_sliding_window_maximum solution = new LC_239_sliding_window_maximum();
+ int[] nums = new int[]{1,-1};
+ int k =1;
+ int[] ans = solution.maxSlidingWindow(nums,k);
+
+ }
+}
+
+
diff --git a/Week02/LC_242_valid_anagram.java b/Week02/LC_242_valid_anagram.java
new file mode 100644
index 000000000..efcd003a3
--- /dev/null
+++ b/Week02/LC_242_valid_anagram.java
@@ -0,0 +1,44 @@
+package Week02;
+
+import java.util.HashMap;
+
+public class LC_242_valid_anagram {
+
+ public boolean isAnagram(String s, String t) {
+ //Brute force
+ //#1. sort, compare one by one
+ //#2, HashMap, tracking charaters
+ //similar with LC_49
+ if (s.length() != t.length()){
+ return false;
+ }
+ HashMap map = new HashMap<>();
+ for(int i =0; i map = new HashMap();
+ for (int n : nums){
+ map.put(n,map.getOrDefault(n,0)+1) ;
+ }
+
+ PriorityQueue> heap = new PriorityQueue<>(new Comparator>() {
+ @Override
+ public int compare(Map.Entry a, Map.Entry b) {
+ return a.getValue() - b.getValue();
+ }
+ });
+
+ for (Map.Entry e: map.entrySet()){
+ heap.add(e);
+ if (heap.size()>k){
+ heap.poll();
+ }
+ }
+
+ int[] topK = new int[k];
+ for (int i = k-1;i>=0;i--){
+ Map.Entry e = heap.poll();
+ if (e == null) break;
+ topK[i] = (Integer) e.getKey();
+ }
+
+ return topK;
+ }
+
+
+ public static void main(String[] args) {
+ int[] nums = new int[]{4,4,4,5,5,6};
+ int k =2;
+// int[] topK = topKFrequent(nums,k);
+ int[] topK = topKFrequent_qsort(nums,k);
+ Arrays.stream(topK).forEach(System.out::println);
+// System.out.println(Arrays.toString(topK));
+// Stream.of(topK).forEach(i->System.out.println(i));
+ }
+
+
+ public static int[] topKFrequent_qsort(int[] nums, int k) {
+ if (k == 0) {
+ return new int[0];
+ }
+ HashMap map = new HashMap();
+ for (int n : nums) {
+ map.put(n, map.getOrDefault(n, 0) + 1);
+ }
+ List> queue = new ArrayList<>(map.size());
+ for (Map.Entry e: map.entrySet()){
+ queue.add(e);
+ }
+ int[] res = new int[k];
+ //利用快排,倒序排序,当pivot==k-1位置时,表示前面k个元素就是top K
+ List> selectedList = quickSelect( queue,0,queue.size()-1, k-1);
+ int idx =0;
+ for(Map.Entry e : selectedList){
+ res[idx++] = e.getKey();
+ }
+ return res;
+ }
+
+ private static List> quickSelect( List> queue, int begin, int end, int k) {
+ if (begin>end){
+ return null;
+ }
+ int pivot = partition(queue,begin,end);
+ if (pivot == k) {
+ List> newList= new ArrayList<>();
+ for (int i =0;i<=k;i++){
+ newList.add(queue.get(i));
+ }
+ return newList;
+ }
+ //如果pivotk,说明太多,对前半部分细分
+ return pivot> queue, int begin, int end) {
+ int pivot = end, count = begin;
+ for (int i = begin;i queue.get(pivot).getValue()){
+ Collections.swap(queue,i,count++);
+ }
+ }
+ Collections.swap(queue,count,pivot);
+ return count;
+ }
+
+}
diff --git a/Week02/LC_49_Group_anagrams.java b/Week02/LC_49_Group_anagrams.java
new file mode 100644
index 000000000..84e8c47ca
--- /dev/null
+++ b/Week02/LC_49_Group_anagrams.java
@@ -0,0 +1,69 @@
+package Week02;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+public class LC_49_Group_anagrams {
+
+ //for each element, convert to char list->sort->convert back to String
+ //use this one as key in a HashMap, value is the List for output
+ // loop through strs, if str is in the hashmap, get the value add str to the list
+ public List> groupAnagrams(String[] strs) {
+ List> res = new ArrayList<>();
+ HashMap> map = new HashMap<>();
+ for (String s : strs){
+ char[] c = s.toCharArray();
+ //this is the key
+ Arrays.sort(c);
+ String key = String.valueOf(c);//c.toString();
+ if (!map.containsKey(key)){
+ map.put(key, new ArrayList<>());
+ }
+ map.get(key).add(s);
+
+ List l = map.get(key);
+ l.add(s);
+ map.put(key,l);
+ }
+
+// for (List v : map.values()){
+// res.add(v);
+// }
+// return res;
+ return new ArrayList(map.values());
+ }
+
+ /*
+ * Solution 2: convert char to int
+ * make a char[26] to keep all char counts.
+ * e.g. "aabccee" will be "2*1*2*0*2*0...",need a separator to identify how count for each chars
+ * dont need to sort here, so save logN for complexity
+ * */
+
+ public List> groupAnagrams_2 (String[] strs) {
+ HashMap> map = new HashMap<>();
+
+ for (String s : strs) {
+ char[] cs = s.toCharArray();
+ int[] count = new int[26];
+ StringBuilder sb = new StringBuilder();
+ for (char c : cs){
+ count[c-'a']++;
+ }
+
+ for (int i=0;i<26;i++){
+ sb.append(count[i]);
+ sb.append("*");
+ }
+ //key will be like "2*1*2*0*2*0..."
+ String key = sb.toString();
+ if (!map.containsKey(key)){
+ map.put(key,new ArrayList());
+ }
+ map.get(key).add(s);
+ }
+ return new ArrayList<>(map.values());
+ }
+}
diff --git a/Week02/LC_94_144_590_429-tree-traversal.java b/Week02/LC_94_144_590_429-tree-traversal.java
new file mode 100644
index 000000000..1d28da14e
--- /dev/null
+++ b/Week02/LC_94_144_590_429-tree-traversal.java
@@ -0,0 +1,202 @@
+package Week02;
+
+import java.util.*;
+
+class BinanryTree_Traversal {
+
+ /*
+ * 深度优先DFS:
+ * 根节点、左孩子和右孩子的相对顺序被细分为前序遍历,中序遍历和后序遍历。
+ *前序(144)~中序(94)~后序(145)遍历可以看成三个时间点
+
+ 前序遍历是在访问左子树之前,对父结点进行操作,也就是在左结点出栈前(!!!出栈即进入以左结点为根的左子树!!!),对父节点do something~
+ 中序遍历是在访问左子树之后,右子树之前,对父结点进行操作,即左结点(代表以左结点为根的子树)出栈后,右结点出栈前,对父节点do something~
+ 后序遍历是在访问左子树,右子树之后,对父结点进行操作,即左右结点都出栈后,对父节点do something~
+ */
+ //144. 二叉树的前序遍历: 从根节点开始,每次迭代弹出当前栈顶元素,并将其孩子节点压入栈中,先压右孩子再压左孩子。
+ public List preorder(TreeNode root) {
+ Stack stack = new Stack<>();
+ List result = new ArrayList<>();
+ if (root ==null){
+ return result;
+ }
+ stack.add(root);
+ while(!stack.isEmpty()){
+ TreeNode node = stack.pop();
+ if (node != null){
+ result.add(node.val);
+ stack.push(node.right);
+ stack.push(node.left);
+ }
+ }
+ return result;
+ }
+
+ //Iteratively
+ /*
+ *94. 二叉树的中序遍历
+ * 迭代 - iteratively
+ * 递归的调用过程是不断往左边走,当左边走不下去了,就打印节点,并转向右边,然后右边继续这个过程。
+ *我们在迭代实现时,就可以用栈来模拟上面的调用过程。
+ * */
+ public List inorderTraversal(TreeNode root) {
+ List res = new ArrayList();
+ Stack stack = new Stack();
+ stack.push(root);
+ while( !stack.empty()){
+ if(root!=null){
+ stack.push(root.left);
+ root = root.left;
+ }
+ else{
+ TreeNode node = stack.pop();
+ if(node != null){
+ res.add(node.val);
+ root = node.right;
+ }
+ }
+ }
+ return res;
+ }
+
+
+ //145: 后序遍历:
+ /*
+ * 与 前序遍历, 从根节点开始,每次迭代弹出当前栈顶元素,并将其孩子节点压入栈中,先压右孩子再压左孩子
+ * 可是对每次迭代弹出节点,把值存入插入结果链表的头部(最后输出)
+ * */
+ public List postorderTraversal(TreeNode root) {
+ Stack stack = new Stack<>();
+ List result = new ArrayList();
+ if (root ==null){
+ return result;
+ }
+ stack.add(root);
+ while(!stack.isEmpty()){
+ TreeNode node = stack.pop();
+ if (node != null){
+ //因为根节点要最后出,所有要再压入栈
+ stack.push(node);
+ stack.push(null); //用null使根节点出栈时去到else
+ //压右孩子
+ if (node.right != null) stack.push(node.right);
+ //压左孩子
+ if (node.left != null) stack.push(node.left);
+ }
+ else{
+ TreeNode output= stack.pop();
+ result.add(output.val);
+ }
+ }
+ return result;
+ }
+ //用相同思路解决中序历遍
+ public List inorderTraversal2(TreeNode root) {
+
+ List res = new ArrayList();
+ Stack stack = new Stack();
+ if (root ==null){
+ return res;
+ }
+ stack.push(root);
+ while(!stack.empty()){
+ TreeNode node = stack.pop();
+ if (node != null){
+ if (node.right != null ) stack.push(node.right);
+ stack.push(node);
+ stack.push(null);
+ if (node.left != null ) stack.push(node.left);
+ }
+ else{
+ res.add(stack.pop().val);
+ }
+ }
+ return res;
+ }
+ //前序 遍历, 因为输出结果是加入ArrayList最后, 所有压栈的顺序和Recursive 是相反的
+ public List preorderTraversal(TreeNode root) {
+
+ List res = new ArrayList();
+ Stack stack = new Stack();
+ if (root ==null){
+ return res;
+ }
+ stack.push(root);
+ while(!stack.empty()){
+ TreeNode node = stack.pop();
+ if (node != null){
+ if (node.right != null ) stack.push(node.right);
+ if (node.left != null ) stack.push(node.left);
+ stack.push(node);
+ stack.push(null);
+ }
+ else{
+ res.add(stack.pop().val);
+ }
+ }
+ return res;
+ }
+
+ // 102. 二叉树的层序遍历
+ public List> levelOrder(TreeNode root) {
+ List> res = new ArrayList<>();
+ if (root == null){
+ return res;
+ }
+ Queue queue = new ArrayDeque();
+
+ queue.add(root);
+ while (!queue.isEmpty()){
+
+ int n =queue.size(); //need the store size to n, as quene size keep changing inside loop
+ List list = new ArrayList();
+ for (int i=0; i> levelOrder_bps(TreeNode root) {
+ List> res = new ArrayList<>();
+ if (root == null){
+ return res;
+ }
+ bps(root,0,res);
+ return res;
+ }
+
+ private void bps(TreeNode curr,int level, List> res) {
+ if (curr == null){
+ return;
+ }
+ // it's new level
+ if (level + 1 > res.size()){
+ res.add(new ArrayList());
+ }
+ res.get(level).add(curr.val);
+ //drill down
+ if (curr.left != null){
+ bps(curr.left,level+1,res);
+ }
+ if (curr.right != null){
+ bps(curr.right, level+1, res);
+ }
+ }
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+ TreeNode(int x) { val = x; }
+ }
+}
diff --git a/Week02/LC_m40_small_k_digits.java b/Week02/LC_m40_small_k_digits.java
new file mode 100644
index 000000000..a273c439e
--- /dev/null
+++ b/Week02/LC_m40_small_k_digits.java
@@ -0,0 +1,26 @@
+package Week02;
+
+import java.util.PriorityQueue;
+
+public class LC_m40_small_k_digits {
+ /*
+ * Solutions:
+ //1. sort: NlogN
+ //2. heap: NlogK
+ //3. quick-sort: logN
+ * */
+ public int[] getLeastNumbers(int[] arr, int k) {
+ if (k == 0) return new int[0];
+ // Java 默认是小根堆,实现大根堆需要重写一下比较器。
+ PriorityQueue heap = new PriorityQueue<>((a, b) -> b - a);
+ for (int i : arr) {
+ if (heap.size() < k) {
+ heap.offer(i);
+ } else if (i < heap.peek()) {
+ heap.poll();
+ heap.offer(i);
+ }
+ }
+ return heap.stream().mapToInt(Integer::intValue).toArray();
+ }
+}
diff --git a/Week02/NOTE.md b/Week02/NOTE.md
index 50de30414..d6635abf7 100644
--- a/Week02/NOTE.md
+++ b/Week02/NOTE.md
@@ -1 +1,94 @@
-学习笔记
\ No newline at end of file
+学习笔记
+ArrayList / List 初始化:
+List list = Arrays.asList(1,2);
+
+Array 初始化:
+int[]{map.get(target-nums[i]),nums[i]};
+
+HashMap 源码:
+为啥要这么多中间变量呢? tab, first, e; n,k 感觉诚心让我们不容易看懂源码:-)
+这些中间变量的作用是存储取出的值? tab = table 有啥作用,为啥不能直接在table上操作?
+
+putVal时,如果hash key 相同的值超过7个时变为TreeNode(红黑树)
+ if (binCount >= 7) { this.treeifyBin(tab, hash); }
+---------------------------------------------
+ final Node getNode(int hash, Object key) {
+ Node[] tab; Node first, e; int n; K k;
+ if ((tab = table) != null && (n = tab.length) > 0 &&
+ (first = tab[(n - 1) & hash]) != null) {
+ if (first.hash == hash && // always check first node
+ ((k = first.key) == key || (key != null && key.equals(k))))
+ return first;
+ if ((e = first.next) != null) {
+ if (first instanceof TreeNode)
+ return ((TreeNode)first).getTreeNode(hash, key);
+ do {
+ if (e.hash == hash &&
+ ((k = e.key) == key || (key != null && key.equals(k))))
+ return e;
+ } while ((e = e.next) != null);
+ }
+ }
+ return null;
+ }
+
+------------------------
+
+ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
+ HashMap.Node[] tab;
+ int n;
+ if ((tab = this.table) == null || (n = tab.length) == 0) {
+ n = (tab = this.resize()).length;
+ }
+
+ Object p;
+ int i;
+ if ((p = tab[i = n - 1 & hash]) == null) {
+ tab[i] = this.newNode(hash, key, value, (HashMap.Node)null);
+ } else {
+ Object e;
+ Object k;
+ if (((HashMap.Node)p).hash == hash && ((k = ((HashMap.Node)p).key) == key || key != null && key.equals(k))) {
+ e = p;
+ } else if (p instanceof HashMap.TreeNode) {
+ e = ((HashMap.TreeNode)p).putTreeVal(this, tab, hash, key, value);
+ } else {
+ int binCount = 0;
+
+ while(true) {
+ if ((e = ((HashMap.Node)p).next) == null) {
+ ((HashMap.Node)p).next = this.newNode(hash, key, value, (HashMap.Node)null);
+ if (binCount >= 7) {
+ this.treeifyBin(tab, hash);
+ }
+ break;
+ }
+
+ if (((HashMap.Node)e).hash == hash && ((k = ((HashMap.Node)e).key) == key || key != null && key.equals(k))) {
+ break;
+ }
+
+ p = e;
+ ++binCount;
+ }
+ }
+
+ if (e != null) {
+ V oldValue = ((HashMap.Node)e).value;
+ if (!onlyIfAbsent || oldValue == null) {
+ ((HashMap.Node)e).value = value;
+ }
+
+ this.afterNodeAccess((HashMap.Node)e);
+ return oldValue;
+ }
+ }
+
+ ++this.modCount;
+ if (++this.size > this.threshold) {
+ this.resize();
+ }
+
+ this.afterNodeInsertion(evict);
+ return null;
+ }
diff --git "a/Week03/.NOTE_images/\345\233\236\346\234\224\347\256\227\346\263\225.png" "b/Week03/.NOTE_images/\345\233\236\346\234\224\347\256\227\346\263\225.png"
new file mode 100644
index 000000000..1cbd75499
Binary files /dev/null and "b/Week03/.NOTE_images/\345\233\236\346\234\224\347\256\227\346\263\225.png" differ
diff --git a/Week03/LC105_construct_binary_tree_from_preorder.java b/Week03/LC105_construct_binary_tree_from_preorder.java
new file mode 100644
index 000000000..3c22ee10d
--- /dev/null
+++ b/Week03/LC105_construct_binary_tree_from_preorder.java
@@ -0,0 +1,46 @@
+package Week03;
+
+import java.util.HashMap;
+
+public class LC105_construct_binary_tree_from_preorder {
+
+ //1.pick up root value of sub_tre from preorder
+ //2.find the root value index in inorder arr (using HashMap to keep the value-index of inorder)
+ //3.假设根节点在中序遍历中索引为 index。从 in_left 到 index - 1 属于左子树,从 index + 1 到 in_right 属于右子树。
+ //4.pre_idx must be globe value
+
+ int pre_idx =0;
+ public TreeNode buildTree(int[] preorder, int[] inorder) {
+
+ int length = preorder.length;
+
+ HashMap in_map = new HashMap<>();
+ for (int i=0;i in_map, int[]preorder){
+ if (in_left>in_right){
+ return null;
+ }
+
+ int root_val = preorder[pre_idx];
+ TreeNode root = new TreeNode(root_val);
+ int in_idx = in_map.get(root_val);
+ pre_idx++;
+
+ root.left = dps(in_left,in_idx-1,in_map,preorder);
+ root.right = dps(in_idx+1,in_right,in_map,preorder);
+ return root;
+ }
+
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+ TreeNode(int x) { val = x; }
+ }
+}
diff --git a/Week03/LC111_min_depth_b_tree.java b/Week03/LC111_min_depth_b_tree.java
new file mode 100644
index 000000000..e03e712b4
--- /dev/null
+++ b/Week03/LC111_min_depth_b_tree.java
@@ -0,0 +1,70 @@
+package Week03;
+
+import Common.BuildBinaryTree;
+import Common.TreeNode;
+
+import java.util.Deque;
+import java.util.LinkedList;
+
+public class LC111_min_depth_b_tree {
+
+ public static void main(String[] args) {
+ Integer[] list = {3,9,20,1,null,15,7};
+ TreeNode root = BuildBinaryTree.buildBinaryTree(list);
+
+ int res = minDepth(root);
+
+ System.out.println("res = "+res);
+
+
+ }
+
+ public static int minDepth(TreeNode root) {
+ if (root == null) return 0;
+ //1.左孩子和有孩子都为空的情况,说明到达了叶子节点,直接返回1即可
+ if (root.right == null && root.left == null) return 1;
+
+ int leftDep = minDepth(root.left);
+ int rightDep = minDepth(root.right);
+
+ //当节点左右孩子有一个为空时,返回不为空的孩子节点的深度
+ //as sometimes return leftDep, sometime return rightDep, need to be rightDep +leftDep + 1
+ //if (root.right == null || root.left == null) return rightDep +leftDep + 1;
+ // 上面公式其实是如下,root.right == null 时, rightDep=0
+ if (root.right == null) return leftDep + 1;
+ if (root.left == null) return rightDep + 1;
+
+ //当节点左右孩子都不为空时,返回左右孩子较小深度的节点值
+ return Math.min(leftDep,rightDep)+1;
+
+ }
+
+
+ public int maxDepth_2(TreeNode root) {
+
+ if (root == null) return 0;
+ Deque queue = new LinkedList<>();
+ queue.addFirst(root);
+ int level = 0;
+ while (!queue.isEmpty()){
+ level++;
+ int size = queue.size();
+ for (int i = 0; i< size; i++){
+ TreeNode curr = queue.pollLast();
+ //when left and right chile are null, mean it's a leaf of tree
+ //we're looking for min, no need to drill down
+ if (curr.left == null && curr.right == null){
+ return level;
+ }
+ if (curr.left != null) {
+ queue.addFirst(curr.left);
+ }
+ if (curr.right !=null) {
+ queue.addFirst(curr.right);
+ }
+ }
+ }
+ //should never reach here.
+ return -1;
+ }
+}
diff --git a/Week03/LC236_lowest_common_ancestor.java b/Week03/LC236_lowest_common_ancestor.java
new file mode 100644
index 000000000..0e80cccfc
--- /dev/null
+++ b/Week03/LC236_lowest_common_ancestor.java
@@ -0,0 +1,40 @@
+package Week03;
+
+
+public class LC236_lowest_common_ancestor {
+ public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+ TreeNode(int x) { val = x; }
+ }
+
+/*
+* 具体思路:
+(1) 如果当前结点 root 等于 NULL,则直接返回 NULL
+(2) 如果 root 等于 p 或者 q ,那这棵树一定返回 p 或者 q
+(3) 然后递归左右子树,因为是递归,使用函数后可认为左右子树已经算出结果,用 left 和 right 表示
+(4) 此时若left为空,那最终结果只要看 right;若 right 为空,那最终结果只要看 left
+(5) 如果 left 和 right 都非空,因为只给了 p 和 q 两个结点,都非空,说明一边一个,因此 root 是他们的最近公共祖先
+(6) 如果 left 和 right 都为空,则返回空(其实已经包含在前面的情况中了)
+* */
+ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+ if (root == null){
+ return null;
+ }
+ if (root == p || root == q) return root; // 本身是祖先
+
+ TreeNode left = lowestCommonAncestor(root.left,p,q);
+ TreeNode right = lowestCommonAncestor(root.right,p,q);
+ if (left == null){ //左边没有两个都在右边
+ return right;
+ }
+ if (right == null){ //右边没有两个都在左边
+ return left;
+ }
+ //一边一个
+ return root;
+ }
+
+ /**/
+}
diff --git a/Week03/LC46_permutations.java b/Week03/LC46_permutations.java
new file mode 100644
index 000000000..14799bb18
--- /dev/null
+++ b/Week03/LC46_permutations.java
@@ -0,0 +1,90 @@
+package Week03;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+class Solution {
+ /*Solution 2:
+ * 就是把数组排列完再放入结果
+ * 以[1, 2|, 3] -> [1, 2, 3|], [3, 2, 1|], [1, 3, 2|]为例,
+ * '|'往后移动一位,得到[1, 2, 3|];[1, 2, 3|]中的3和1位置交换,
+ * 得到[3, 2, 1|];[1, 2, 3|]中的3和2交换位置,得到[1, 3, 2|]。
+ * */
+
+ public List> permute(int[] nums) {
+ List> res = new ArrayList<>();
+ if (nums == null || nums.length == 0) {
+ return res;
+ }
+ // don't need to sort
+ Arrays.sort(nums);
+ backtrack(res, nums, 0);
+ return res;
+ }
+
+ private void backtrack(List> res, int[] nums, int level) {
+ if (nums.length == level) {
+ res.add(Arrays.stream(nums).boxed().collect(Collectors.toList()));
+ return;
+ }
+ //no swap, original list
+ backtrack(res, nums, level + 1);
+
+ for (int i = 0; i < level; i++) {
+ swap(nums, i, level);
+ backtrack(res, nums, level + 1);
+ swap(nums, i, level);
+ }
+ return;
+ }
+
+ public static void swap(int[] arr, int i, int j) {
+ arr[i] = (arr[i] + arr[j]) - (arr[j] = arr[i]);
+ }
+
+ /*********************Solution 2:*******************************************************************
+ 取出不同的数放入结果
+
+ */
+ int length;
+
+ public List> permute_1(int[] nums) {
+ List> res = new ArrayList<>();
+ if (nums == null || nums.length == 0) {
+ return res;
+ }
+ length = nums.length;
+ List list = new ArrayList<>();
+ boolean[] used = new boolean[length];
+ dps(res, nums, list, used);
+ return res;
+ }
+
+ private void dps(List> res, int[] nums, List list, boolean[] used) {
+ if (list.size() == length) {
+ res.add(new ArrayList(list));
+ return;
+ }
+ // 每次要用所有可能的数
+ for (int i = 0; i < length; i++) {
+ if (!used[i]) {
+ list.add(nums[i]);
+ used[i] = true;
+ dps(res, nums, list, used);
+ used[i] = false;
+ list.remove(list.size() - 1);
+ }
+ }
+ }
+}
+
+public class LC46_permutations {
+
+ public static void main(String[] args) {
+ int[] nums = new int[]{1, 2, 3};
+ Solution solution = new Solution();
+ List> res = solution.permute(nums);
+ }
+}
diff --git a/Week03/LC47_permutations_ii.java b/Week03/LC47_permutations_ii.java
new file mode 100644
index 000000000..3276c8077
--- /dev/null
+++ b/Week03/LC47_permutations_ii.java
@@ -0,0 +1,99 @@
+package Week03;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class LC47_permutations_ii {
+
+ /*
+ * 先排序,有相同值跳过一个,把数组排列完再放入结果
+ * */
+
+ public List> permuteUnique(int[] nums) {
+ List> res = new ArrayList<>();
+ if (nums == null || nums.length == 0) {
+ return res;
+ }
+ Arrays.sort(nums);
+ backtrack(res, nums, 0);
+ return res;
+ }
+
+ private void backtrack(List> res, int[] nums, int level) {
+ if (nums.length == level) {
+ res.add(Arrays.stream(nums).boxed().collect(Collectors.toList()));
+ return;
+ }
+ backtrack(res, nums, level + 1);
+ for (int i = 0; i < level; i++) {
+ //avoid duplicated,need to be break for the same value
+ if (nums[i] == nums[level]) {
+ break;
+ }
+ swap(nums, i, level);
+ backtrack(res, nums, level + 1);
+ swap(nums, i, level);
+ }
+ return;
+ }
+
+ private void swap(int[] nums, int i, int j) {
+ // must be value of i assign to j first
+ nums[i] = (nums[i] + nums[j]) - (nums[j] = nums[i]);
+ }
+
+/*Solution2:
+
+Bruit force*/
+
+ int length;
+
+ public List> permuteUnique_1(int[] nums) {
+ List> res = new ArrayList<>();
+ if (nums == null || nums.length == 0) {
+ return res;
+ }
+ length = nums.length;
+ List list = new ArrayList<>();
+ Set set = new HashSet<>();
+ boolean[] used = new boolean[length];
+ dps(res, nums, list, used, set);
+ return res;
+ }
+
+ private void dps(
+ List> res, int[] nums, List list, boolean[] used, Set set) {
+ if (list.size() == length) {
+ StringBuilder sb = new StringBuilder();
+ for (Integer i : list) {
+ sb.append(i);
+ sb.append("-");
+ }
+ if (!set.contains(sb.toString())) {
+ res.add(new ArrayList(list));
+ set.add(sb.toString());
+ }
+ return;
+ }
+
+ for (int i = 0; i < length; i++) {
+ if (!used[i]) {
+ list.add(nums[i]);
+ used[i] = true;
+ dps(res, nums, list, used, set);
+ used[i] = false;
+ list.remove(list.size() - 1);
+ }
+ }
+ }
+}
+
+
+class Test {
+
+ public static void main(String[] args) {
+ int[] nums = new int[]{2, 2, 1, 1};
+ LC47_permutations_ii solution = new LC47_permutations_ii();
+ List> res = solution.permuteUnique(nums);
+ }
+}
diff --git a/Week03/LC51_n_queens.java b/Week03/LC51_n_queens.java
new file mode 100644
index 000000000..6c14c7d9f
--- /dev/null
+++ b/Week03/LC51_n_queens.java
@@ -0,0 +1,137 @@
+package Week03;
+
+import Week08.LC52_n_queens_ii;
+
+import java.util.*;
+
+public class LC51_n_queens {
+ static class Solution {
+/*
+* Bitwise Operators
+1.通过位运算,得到长度为n的bits,可以放queen位置为1,其他为0
+2.历遍bits(while bits>0)
+3.得到最低位的1,bits & -bits;
+4.下探下一行,要把最低位的1放入记录值(row+1,(cols|p),((master|p)*2),((slaver|p)/2),n)
+5.把bits中的最低位的1去掉。
+* */
+
+ public List> solveNQueens(int n) {
+ List> res = new ArrayList<>();
+ if (n <= 0) {
+ return res;
+ }
+ List bitRes = new ArrayList<>();
+
+ dfs(n, 0, 0, 0, 0, bitRes, res);
+ return res;
+ }
+
+ private void dfs(int n, int row, int col, int master, int slaver, List bitRes, List> res) {
+ if (row == n) {
+ List board = convert(bitRes, n);
+ res.add(board);
+ return;
+ }
+ int bits = ~(col | master | slaver) & ((1 << n) - 1);
+ while (bits > 0) {
+ int p = bits & -bits; //得到最低位的1
+ bitRes.add(p);
+ dfs(n, row + 1, col | p, (master | p) << 1, (slaver | p) >> 1, bitRes, res);
+ bitRes.remove(bitRes.size() - 1);
+ bits = bits & (bits - 1);
+ }
+ }
+
+ private List convert(List bitRes, int n) {
+ List res = new ArrayList<>();
+ for (int bitIdx : bitRes) {
+ StringBuilder sb = new StringBuilder();
+ int count = 0;
+ //like '0100',move 3 time, the the '1' position.
+ while (bitIdx > 0) {
+ bitIdx >>= 1;
+ count++;
+ }
+ for (int j = 0; j < n; j++) {
+ //as bitwise start with position 1, array start with 0.
+ if (j == count-1) {
+ sb.append("Q");
+ } else {
+ sb.append(".");
+ }
+ }
+ res.add(sb.toString());
+ }
+ return res;
+ }
+
+ //检测主对角线或者副对角线,就是如果row+col值相同说明在相同主对角线上,row-col值相同,说明在同一副对角线上
+ public List> solveNQueens_2(int n) {
+ List> res = new ArrayList<>();
+ if (n <= 0) {
+ return res;
+ }
+ Set cols = new HashSet<>();
+ Set master = new HashSet<>();
+ Set slaver = new HashSet<>();
+ Stack temp = new Stack<>();
+ backtrack(n, cols, master, slaver, temp, 0, res);
+ return res;
+ }
+
+ private void backtrack(int n, Set cols, Set master, Set slaver,
+ Stack stack, int row, List> res) {
+ if (row == n) {
+ List board = convert2board(stack, n);
+ res.add(board);
+ return;
+ }
+ // 针对每一列,尝试是否可以放置
+ for (int i = 0; i < n; i++) {
+ if (!cols.contains(i)
+ //row+col值相同说明在相同主对角线上
+ && !master.contains(i + row)
+ //row-col值相同,说明在同一副对角线上
+ && !slaver.contains(i - row)
+ ) {
+ //记录queen位置
+ stack.push(i);
+ cols.add(i);
+ master.add(i + row);
+ slaver.add(i - row);
+ backtrack(n, cols, master, slaver, stack, row + 1, res);
+
+ //回朔
+ stack.pop();
+ cols.remove(i);
+ master.remove(i + row);
+ slaver.remove(i - row);
+ }
+ }
+
+ }
+
+ private List convert2board(Stack stack, int n) {
+ List board = new LinkedList<>();
+ for (Integer num : stack) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < n; i++) {
+ if (i == num) {
+ sb.append("Q");
+ } else {
+ sb.append(".");
+ }
+ }
+ board.add(sb.toString());
+ }
+ return board;
+ }
+ }
+
+ public static void main(String[] args) {
+ Solution solution = new Solution();
+ List> res = solution.solveNQueens(4);
+ System.out.println("result:"+res);
+
+ }
+}
diff --git a/Week03/LC_17_Letter_combinations_of_phone.java b/Week03/LC_17_Letter_combinations_of_phone.java
new file mode 100644
index 000000000..fef0c886e
--- /dev/null
+++ b/Week03/LC_17_Letter_combinations_of_phone.java
@@ -0,0 +1,52 @@
+package Week03;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class LC_17_Letter_combinations_of_phone {
+
+ //use a map to keep number->letter
+ //number of digits will be number of letter that choose for map
+ public static List letterCombinations(String digits) {
+ List res = new ArrayList<>();
+ if (digits.length() == 0) return res;
+
+ HashMap map = new HashMap(){{
+ put("2", "abc");
+ put("3", "def");
+ put("4", "ghi");
+ put("5", "jkl");
+ put("6", "mno");
+ put("7", "pqrs");
+ put("8", "tuv");
+ put("9", "wxyz");
+ }};
+ generate(res,digits,0,map,new StringBuilder());
+ return res;
+ }
+
+ private static void generate(List res, String digits, int level, HashMap map, StringBuilder s) {
+ if (level == digits.length()){
+ res.add(s.toString());
+ return;
+ }
+ //current process
+ String key = String.valueOf(digits.charAt(level));
+ String letters = map.get(key);
+
+ for (int i =0; i res =letterCombinations("23578235782357823578");
+ System.out.println("Done!");
+ }
+}
diff --git a/Week03/LC_50_powx_n.java b/Week03/LC_50_powx_n.java
new file mode 100644
index 000000000..0d4a6ef87
--- /dev/null
+++ b/Week03/LC_50_powx_n.java
@@ -0,0 +1,31 @@
+package Week03;
+
+public class LC_50_powx_n {
+/*
+* Solution 1.
+* Divide & Conque
+* */
+ public double myPow_1(double x, int n) {
+ //1. terminator
+ //2. process (split your big problem)
+ //3. drill down (sub-problems)
+ //4. merge(sub-result)
+ //5. reverse states
+ //Java 代码中 int32, n∈[−2147483648,2147483647] , 因此当 n = -2147483648n=−2147483648 时执行 n = -nn=−n 会因越界而赋值出错
+ long k = n;
+ if (n<0) {
+ k = -k;
+ }
+ double s = quickPow(x, k);
+ return n<0? 1/s: s;
+ }
+
+ private double quickPow (double x, long n) {
+ if (n==0){
+ return 1.0;
+ }
+ double s = quickPow(x, n/2);
+ return (n%2==0)? s*s : s*s*x;
+ }
+
+}
diff --git a/Week03/LC_77_combinations.java b/Week03/LC_77_combinations.java
new file mode 100644
index 000000000..7edef458b
--- /dev/null
+++ b/Week03/LC_77_combinations.java
@@ -0,0 +1,37 @@
+package Week03;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LC_77_combinations {
+
+ //iterrate 1..n
+ //recursive
+ //every layer, need a loop to get rest of value for n, until reach k.
+ //在每一层中,把余下的值加到list中直到k,然后输出list.
+ public List> combine(int n, int k) {
+ List> ans = new ArrayList<>();
+ if (k == 0 ){
+ return ans;
+ }
+ List list = new ArrayList<>();
+ dps(ans, list, 1, k ,n);
+ return ans;
+ }
+ private void dps(List> ans, List list, int begin, int k, int n){
+ if (list.size() == k){
+ //need new a list
+ //here is the output of stack
+ ans.add(new ArrayList<>(list));
+ return;
+ }
+
+ for (int i = begin;i <= n;i++) {
+ list.add(i);
+ //add 1 to Stack, then 2, then 3 .. all n add to stack.
+ //then go to for loop. add second number.
+ dps(ans,list, i+1,k,n);
+ list.remove(list.size()-1);
+ }
+ }
+}
diff --git a/Week03/LC_78_subsets.java b/Week03/LC_78_subsets.java
new file mode 100644
index 000000000..df50eb72d
--- /dev/null
+++ b/Week03/LC_78_subsets.java
@@ -0,0 +1,60 @@
+package Week03;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LC_78_subsets {
+
+ /* //Solutions:
+ * 1. Recusive
+ * dps: for any element, there has only two options:
+ * select or no-select. in every level save the result to output
+ * as we change the param, need to reverse the changes
+ * */
+ public List> subsets(int[] nums) {
+ List> ans = new ArrayList<>();
+ if (nums.length == 0 ){
+ return ans;
+ }
+ List list = new ArrayList<>();
+ dfs(ans,nums,list,0);
+ return ans;
+ }
+
+ private void dfs(List> ans, int[] nums, List list, int level) {
+ //走到的数组nums的末尾了
+ if (level == nums.length){
+ //走到的数组nums的末尾了,把结果放入answer
+ ans.add(list);
+ return;
+ }
+ dfs(ans,nums,list,level+1);
+ list.add(nums[level]);
+ dfs(ans,nums,list,level+1);
+ list.remove(list.size()-1);
+ }
+
+ /*
+ * 2. Iterative
+ * 逐个枚举,空集的幂集只有空集,每增加一个元素,让之前幂集中的每个集合,追加这个元素,就是新增的子集。
+ *
+ * */
+ public List> subsets_iterate(int[] nums) {
+ List> ans = new ArrayList<>();
+ //加一个空集[[]]
+ ans.add(new ArrayList());
+ for (int n: nums) {
+ int size = ans.size();
+ for (int i =0; i