From d9c30db730ac9b9ea4e599a29a1b6124a100fa97 Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Wed, 16 Sep 2020 20:29:14 +0800 Subject: [PATCH 01/12] week01 assignment --- Week_01/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Week_01/README.md b/Week_01/README.md index 50de3041..444bbd64 100644 --- a/Week_01/README.md +++ b/Week_01/README.md @@ -1 +1,2 @@ -学习笔记 \ No newline at end of file +学习笔记 +学习使我快乐 From 2e8d8778c5be3960242bd940fa562bde2aaa5b9b Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Sun, 27 Sep 2020 22:52:14 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Week_01/Merge Two Sorted Lists.java | 37 ++++++++++ Week_01/Min Stack.java | 102 ++++++++++++++++++++++++++++ Week_01/Move Zeroes.java | 33 +++++++++ Week_01/README.md | 14 +++- 4 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 Week_01/Merge Two Sorted Lists.java create mode 100644 Week_01/Min Stack.java create mode 100644 Week_01/Move Zeroes.java diff --git a/Week_01/Merge Two Sorted Lists.java b/Week_01/Merge Two Sorted Lists.java new file mode 100644 index 00000000..5e5ed6bd --- /dev/null +++ b/Week_01/Merge Two Sorted Lists.java @@ -0,0 +1,37 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + //方法遍历依次比较大小插入,直到有一条遍历完 + +class Solution { + public ListNode mergeTwoLists(ListNode l1, ListNode l2) { + ListNode l = new ListNode(); + ListNode p1 = l1, p2 = l2; + ListNode cur = l; + while (p1 != null && p2 != null) { + if (p1.val <= p2.val) { + cur.next = p1; + p1 = p1.next; + cur = cur.next; + } else { + cur.next = p2; + p2 = p2.next; + cur = cur.next; + } + } + if(p1 == null) { + cur.next = p2; + } + if(p2 == null) { + cur.next = p1; + } + return l.next; + } +} \ No newline at end of file diff --git a/Week_01/Min Stack.java b/Week_01/Min Stack.java new file mode 100644 index 00000000..e6df2e5d --- /dev/null +++ b/Week_01/Min Stack.java @@ -0,0 +1,102 @@ +//方法一 利用数组模拟栈实现 +//方法二 利用栈与辅助栈实现 +//方法三 利用链表模拟栈实现 + +// class MinStack { +// //方法一 +// int[] min;//存储每次最小值 +// int[] stack; +// int head; +// /** initialize your data structure here. */ +// public MinStack() { +// stack = new int[10000]; +// min = new int[10000]; +// head = 0; +// } + +// public void push(int x) { +// if (head < stack.length) { +// stack[head] = x; +// if(head == 0 || min[head-1] > x) +// min[head] = x; +// else +// min[head] = min[head-1]; +// head++; +// } +// // System.out.print(head); +// } + +// public void pop() { +// if(head > 0) +// head--; +// } + +// public int top() { +// if(head > 0) +// return stack[head-1]; +// else +// return stack[0]; +// } + +// public int getMin() { +// // int min = stack[0]; +// // for(int i = 0 ; i < head; i++) { +// // if(min > stack[i]) +// // min = stack[i]; +// // } +// if(head > 0) +// return min[head-1]; +// else +// return min[head]; +// } + + +// } + +class MinStack { + private Node head; + + public void push(int x) { + if(head == null) + head = new Node(x, x); + else + head = new Node(x, Math.min(x, head.min), head); + } + + public void pop() { + head = head.next; + } + + public int top() { + return head.val; + } + + public int getMin() { + return head.min; + } + + private class Node { + int val; + int min; + Node next; + + private Node(int val, int min) { + this(val, min, null); + } + + private Node(int val, int min, Node next) { + this.val = val; + this.min = min; + this.next = next; + } + } +} + +/** + * Your MinStack object will be instantiated and called as such: + * MinStack obj = new MinStack(); + * obj.push(x); + * obj.pop(); + * int param_3 = obj.top(); + * int param_4 = obj.getMin(); + */ \ No newline at end of file diff --git a/Week_01/Move Zeroes.java b/Week_01/Move Zeroes.java new file mode 100644 index 00000000..444fc849 --- /dev/null +++ b/Week_01/Move Zeroes.java @@ -0,0 +1,33 @@ +class Solution { + // public void moveZeroes(int[] nums) { + // int j = 0; + // for (int i = 0; i < nums.length; i++) { + // if (nums[i] != 0) { + // nums[j] = nums[i]; + // if(i != j){ + // nums[i] = 0; + // } + // j++; + // } + // } + // } + //暴力法o(n*n) + //双指针 + public void moveZeroes(int[] nums) { + for (int i = 0,j = 0; j < nums.length ; j++) { + if(nums[j] != 0) { + nums[i] = nums[j]; + if(i != j){ + nums[j] = 0; + } + i++; + } + + } + + } +} +//方法一 挨着挨着移动 +//方法二 开新数组记录零点的位置,再操作原数组,最后补零 +//***方法三 index增加一个j来记录下一个非零元素位置,遇到非零元素交换元素,一次遍历即可 +//***方法四 两次遍历,第一次把所有非零元素移到规定位置,第二次遍历把剩下的元素置零 \ No newline at end of file diff --git a/Week_01/README.md b/Week_01/README.md index 444bbd64..3b2095b9 100644 --- a/Week_01/README.md +++ b/Week_01/README.md @@ -1,2 +1,12 @@ -学习笔记 -学习使我快乐 +学习笔记 学习使我快乐 +本周总结9/27 + +1.五遍刷题法: + 第一遍:5分钟:读题加思考;直接看解法;背诵、默写好的解法; + 第二遍:马上自己写;多种解法比较、优化; + 第三遍:过了一天后,重复做题;不同解法熟练程度; + 第四遍:一周后:反复练习; + 第五遍:面试前一周恢复性训练; +2.学会使用谷歌搜索java源代码、文档 +3.学会升维的思想空间换时间 +4.双指针法,把问题拆解成最近的子问题 \ No newline at end of file From 5c80c33b44ae067f083dcaad3924e1b9438bf263 Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Fri, 2 Oct 2020 16:41:33 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E5=AD=A6=E4=B9=A0=E6=80=BB=E7=BB=932.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Week_01/MyDeque.java | 21 ++ "Week_01/Queue\345\222\214PriorityQueue.md" | 229 ++++++++++++++++++++ Week_01/README.md | 92 +++++++- 3 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 Week_01/MyDeque.java create mode 100644 "Week_01/Queue\345\222\214PriorityQueue.md" diff --git a/Week_01/MyDeque.java b/Week_01/MyDeque.java new file mode 100644 index 00000000..587f4e02 --- /dev/null +++ b/Week_01/MyDeque.java @@ -0,0 +1,21 @@ +import java.util.Deque; +import java.util.LinkedList; + +public class MyDeque { + public static void main(String[] args) { + Deque deque = new LinkedList(); + deque.offerFirst("a"); + deque.offerFirst("b"); + deque.offerFirst("c"); + System.out.println(deque); + + String str = deque.peekFirst(); + System.out.println(str); + System.out.println(deque); + + while (deque.size() > 0) { + System.out.println(deque.pollFirst()); + } + System.out.println(deque); + } +} diff --git "a/Week_01/Queue\345\222\214PriorityQueue.md" "b/Week_01/Queue\345\222\214PriorityQueue.md" new file mode 100644 index 00000000..9e154a56 --- /dev/null +++ "b/Week_01/Queue\345\222\214PriorityQueue.md" @@ -0,0 +1,229 @@ +# Java中Queue和PriorityQueue的实现 + +## Queue的实现 + +Java中`Queue`是一个接口,定义了如下几个方法: + +- `add(E): boolean`:往queue中插入元素,成功返回true,失败抛出相应的异常: + - 空间不足:`IllegalStateException` + - 空指针:`NullPointerException` + - 类型转换:`ClassCastException` + - 添加的元素的某些属性使其不能被加入queue中:`IllegalArgumentException`(不太清楚具体是什么情形) +- `offer(E): boolean`: 往queue中插入元素,成功返回true,失败返回false。与`add(E)`相比,不会抛出`IllegalStateException`,遇到其他情况仍然会抛出异常。 +- `remove(): E`:从头部移除一个元素并返回。如果queue为空将抛出`NoSuchElementException` +- `poll(): E`:从头部移除一个元素并返回。如果queue为空将返回`null` +- `element(): E`:取得queue的头部元素(第一个元素),并且不会删除该元素。如果queue为空,抛出`NoSuchElementException` +- `peek(): E`:取得queue的头部元素(第一个元素),并且不会删除该元素。如果queue为空,返回`null` + +## PriorityQueue + +`PriorityQueue`继承了`AbstractQueue`抽象类,该抽象类实现了`Queue`接口。根据注释,Java中的`PriorityQueue`应该是根据最大/最小堆实现的(完全二叉树,结点`queue[i]`的左右孩子分别为`queue[2*i+1]和queue[2*i+2]`)。 + +### 关键字段 + +- `transient Object[] queue;`:数据存放 +- `private int size = 0`:当前大小 +- `private final Comparator comparator`:用于对堆中元素比较。如果为空,则使用数据元素自带的排序方式 +- `private static final int DEFAULT_INITIAL_CAPACITY = 11;`:初始默认的大小,`queue = new Object[initialCapacity]` + +### 核心方法 + +1. `add(E): boolean`:调用`offer(E): boolean` + +2. `offer(E): boolean`: + + ```java + public boolean offer(E e) { + if (e == null) + throw new NullPointerException(); + modCount++; // 修改过的次数增加 + int i = size; + if (i >= queue.length) + grow(i + 1); // 增加queue这个数组的大小 + size = i + 1; + if (i == 0) + queue[0] = e; + else + siftUp(i, e); // 从底部向上,将上面元素往下过滤。因此Java中PriorityQueue的插入应该不是O(1)的,而是O(logn) + return true; + } + ``` + +3. `peek(): E`: + + ```java + public E peek() { + // 如果当前数组不是空的,返回第一个元素,否则返回null + return (size == 0) ? null : (E) queue[0]; + } + ``` + +4. `remove(Object): boolean`: + + ```java + public boolean remove(Object o) { + int i = indexOf(o); + if (i == -1) + return false; + else { + removeAt(i); // 调用removeAt()方法,该方法中会对堆进行调整 + return true; + } + } + ``` + +5. `poll(): E` + + ```java + public E poll() { + if (size == 0) + return null; + int s = --size; + modCount++; + E result = (E) queue[0]; + E x = (E) queue[s]; + queue[s] = null; + if (s != 0) + siftDown(0, x); // 删除后调整堆,将堆最后一个元素放到堆顶,自顶向下过滤,将较小/较大的元素往上移动 + return result; + } + ``` + +6. `removeAt(int): E`: + + ```java + private E removeAt(int i) { + // assert i >= 0 && i < size; + modCount++; + int s = --size; + if (s == i) // removed last element + queue[i] = null; // 移除最后一个元素不需要对堆进行调整 + else { + E moved = (E) queue[s]; + queue[s] = null; + // 可以看成是对以queue[i]为根节点的堆进行删除操作,将该子堆的最后一个元素移动到堆顶向下过滤 + siftDown(i, moved); + if (queue[i] == moved) { + // 如果queue[i] == moved,说明被移动到堆顶的元素已经是该元素中最小/最大的,此时从该位置进行向上过滤,保持堆的性质 + siftUp(i, moved); // + if (queue[i] != moved) + return moved; + } + } + return null; + } + ``` + +#### `siftDown`和`siftUp` + +为方便起见,假设下面的操作都是基于最小堆的。 + +1. `siftUp()` + + ```java + private void siftUp(int k, E x) { + // 调用具体的siftUp方法 + if (comparator != null) + siftUpUsingComparator(k, x); + else + siftUpComparable(k, x); + } + + private void siftUpComparable(int k, E x) { + Comparable key = (Comparable) x; + while (k > 0) { + int parent = (k - 1) >>> 1; + Object e = queue[parent]; + if (key.compareTo((E) e) >= 0) // 将当前元素与其父亲进行比较,若结果<0,则将该元素往上移动,否则该元素已经找到了合适的位置,堆调整完毕 + break; + queue[k] = e; // 父亲向下移动 + k = parent; + } + queue[k] = key; + } + + @SuppressWarnings("unchecked") + private void siftUpUsingComparator(int k, E x) { + // 与上面的方法是一样的逻辑,只是比较时使用的方法有差异 + while (k > 0) { + int parent = (k - 1) >>> 1; + Object e = queue[parent]; + if (comparator.compare(x, (E) e) >= 0) + break; + queue[k] = e; + k = parent; + } + queue[k] = x; + } + ``` + +2. `siftDown()` + + ```java + private void siftDown(int k, E x) { + // siftDown入口 + if (comparator != null) + siftDownUsingComparator(k, x); + else + siftDownComparable(k, x); + } + + @SuppressWarnings("unchecked") + private void siftDownComparable(int k, E x) { + // 为了保证最小堆的性质,可以认为将当前堆中最后一个元素移动到堆顶,每次将当前结点及其左右孩子中最小的元素放在当前位置,从而保证最小堆的性质得到满足。 + Comparable key = (Comparable)x; + // 层序遍历中最后一个非叶子结点,如果遍历过程中索引超过了这个值,说明已经不需要再继续循环进行调整了 + int half = size >>> 1; // loop while a non-leaf + while (k < half) { + int child = (k << 1) + 1; // assume left child is least + Object c = queue[child]; // 左孩子 + int right = child + 1; // 右孩子 + if (right < size && + ((Comparable) c).compareTo((E) queue[right]) > 0) + // 若右孩子存在,并且左孩子大于右孩子,说明右孩子是三者中最小的,将右孩子往上移动 + c = queue[child = right]; + // 否则右孩子不存在或左孩子小于右孩子。此时需要比较左孩子和当前结点 + if (key.compareTo((E) c) <= 0) + // 若当前结点的值已经小于左孩子,那么当前结点已经到达了合适的位置,堆重新调整到满足最小堆的状态,退出循环 + break; + // 否则左孩子最小,左孩子往上移动 + queue[k] = c; + k = child; + } + queue[k] = key; + } + + @SuppressWarnings("unchecked") + private void siftDownUsingComparator(int k, E x) { + int half = size >>> 1; + while (k < half) { + int child = (k << 1) + 1; + Object c = queue[child]; + int right = child + 1; + if (right < size && + comparator.compare((E) c, (E) queue[right]) > 0) + c = queue[child = right]; + if (comparator.compare(x, (E) c) <= 0) + break; + queue[k] = c; + k = child; + } + queue[k] = x; + } + ``` + + #### `heapify()`:建堆过程,时间复杂度O(n) + + ```java + private void heapify() { + // 时间复杂度O(n),具体推导忘记了…… + // 从底部开始,调整每一棵子树,使其成为一个最小堆 + // 对于最底部的子树而言,它高度最多为2,对其进行siftDown,可以保证该子树为最小堆 + // 每次循环中,对于每个子堆的堆顶而言,它的左右孩子经过之前的调整一定是最小堆,这时再siftDown,形成一个更大的最小堆。(每次当前元素移动时,不满足堆的性质一定只有以当前元素所在位置为根的子树,当前元素不能再向下移动时,调整完成) + for (int i = (size >>> 1) - 1; i >= 0; i--) + siftDown(i, (E) queue[i]); + } + ``` + + + diff --git a/Week_01/README.md b/Week_01/README.md index 3b2095b9..a7e86563 100644 --- a/Week_01/README.md +++ b/Week_01/README.md @@ -9,4 +9,94 @@ 第五遍:面试前一周恢复性训练; 2.学会使用谷歌搜索java源代码、文档 3.学会升维的思想空间换时间 -4.双指针法,把问题拆解成最近的子问题 \ No newline at end of file +4.双指针法,把问题拆解成最近的子问题 + + + +[TOC] + +#数据结构 + +• 一维: + • 基础:数组 array (string), 链表 linked list + • 高级:栈 stack, 队列 queue, 双端队列 deque, 集合 set, 映射 map (hash or map), etc + +• 二维: + • 基础:树 tree, 图 graph + • 高级:二叉搜索树 binary search tree (red-black tree, AVL), 堆 heap, 并查集 disjoint set, 字典树 Trie, etc + +• 特殊: + • 位运算 Bitwise, 布隆过滤器 BloomFilter • LRU Cache + +#算法 + +- If-else, switch —> branch +- for, while loop —> Iteration +- 递归 Recursion (Divide & Conquer, Backtrace) +- 搜索 Search: 深度优先搜索 Depth first search, 广度优先搜索 Breadth first search, A*, etc +- 动态规划 Dynamic Programming +- 二分查找 Binary Search +- 贪心 Greedy +- 数学 Math , 几何 Geometry + +#Big O notation + +* O(1): Constant Complexity 常数复杂度 +* O(log n): Logarithmic Complexity 对数复杂度 +* O(n): Linear Complexity 线性时间复杂度 +* O(n^2): N square Complexity 平方 +* O(n^3): N cubic Complexity 立方 +* O(2^n): Exponential Growth 指数 +* O(n!): Factorial 阶乘 + +# 空间复杂度 + +* 数组的长度 +* 递归的深度 + +# 数组 + +* 数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。 +* 下标查询的时间复杂度为O(1), 增加和删除的时间复杂度为O(n) + +# 链表 + +* 通过“指针”将一组零散的内存块串联起来使用 +* 查询时间复杂度O(n),增加和删除的时间复杂度为O(1) +* 将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,指向了这个变量,通过指针就能找到这个变量。 + +~~~ +单链表插入:插入x节点,当前指针指向p +注意顺序,防止内存泄漏 +1. x->next = p->next; // 将x的结点的next指针指向b结点; +2. p->next = x; // 将p的next指针指向x结点; +当向一个空链表中插入第一个结点,需进行下面这样的特殊处理,其中 head 表示链表的头结点。所以,对于单链表的插入操作,第一个结点和其他结点的插入逻辑是不一样的。 +if (head == null) { head = new_node;} +~~~ + +~~~ +单链表结点删除操作,如果要删除结点 p 的后继结点: +p->next = p->next->next; +如果要删除链表中的最后一个结点,需要特殊处理。 +if (head->next == null) { head = null;} +~~~ + +# 跳表 + +* 给链表升维,在链表上加入多级索引的结构 +* 第 k 级索引的结点个数是第 k-1 级索引的结点个数的 1/2,那第 k级索引结点的个数就是 n/(2k) +* 跳表中查询任意数据的时间复杂度就是 O(logn),插入和删除也是O(logn) + +# 栈 + +* 当某个数据集合只涉及在一端插入和删除数据,并且满足后进先出、先进后出的特性,就应该首选“栈”这种数据结构。 +* 栈主要包含两个操作,入栈和出栈,也就是在栈顶插入一个数据和从栈顶删除一个数据。 +* 栈既可以用数组来实现,也可以用链表来实现。用数组实现的栈,我们叫作顺序栈,用链表实现的栈,我们叫作链式栈。 +* 时间复杂度和空间复杂度都为O(1) + +# 队列 + +* 先进者先出,这就是典型的“队列” +* 最基本的操作也是两个:入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取一个元素。 +* 跟栈一样,队列可以用数组来实现,也可以用链表来实现。用数组实现的栈叫作顺序栈,用链表实现的栈叫作链式栈。同样,用数组实现的队列叫作顺序队列,用链表实现的队列叫作链式队列。 + From e5f7e1eb72fac306f0378d262d155fa65b4885a1 Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Sun, 11 Oct 2020 20:52:50 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8F=90=E4=BA=A41.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Week_02/GroupAnagrams.java | 93 ++++++++++++++++++++++++++++++++++++++ Week_02/README.md | 25 +++++++++- Week_02/TwoSum.java | 46 +++++++++++++++++++ Week_02/ValidAnagram.java | 26 +++++++++++ 4 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 Week_02/GroupAnagrams.java create mode 100644 Week_02/TwoSum.java create mode 100644 Week_02/ValidAnagram.java diff --git a/Week_02/GroupAnagrams.java b/Week_02/GroupAnagrams.java new file mode 100644 index 00000000..f8e4bb7a --- /dev/null +++ b/Week_02/GroupAnagrams.java @@ -0,0 +1,93 @@ +//还有一种质数相乘法 风险时 容易溢出 +// 算术基本定理,又称为正整数的唯一分解定理,即:每个大于1的自然数,要么本身就是质数,要么可以写为2个以上的质数的积,而且这些质因子按大小排列之后,写法仅有一种方式。 +//故可以利用 每个字母用不同的质数表示,字符串的键值为 质数之积 来表示 + + +class Solution {//按计数分类 +//构建一个StringBuilder类型变量作为 key 值 #a#b#c#d.....#z +//每个字母的位置存储对应字母的出现次数,依次分类 +//利用一个哈希表存储分类的结果,最后返回 +// // 时间复杂度:O(NK),其中 N 是 strs 的长度,而 K 是 strs 中字符串的最大长度。计算每个字符串的字符串大小是线性的,我们统计每个字符串。 +// // 空间复杂度:O(NK),排序存储在 res 中的全部信息内容 + public List> groupAnagrams(String[] strs) { + if (strs.length == 0) return new ArrayList<>(); + Map res = new HashMap(); + for (String s : strs) { + int[] arr = new int[26]; + for (char ch : s.toCharArray()) { + arr[ch - 'a']++; + } + StringBuilder temp = new StringBuilder(""); + for (int i = 0; i < 26; i++) { + temp.append('#'); + temp.append(arr[i]); + } + String key = temp.toString(); + if (!res.containsKey(key)) res.put(key, new ArrayList()); + res.get(key).add(s); + } + return new ArrayList(res.values()); + } +} + +// class Solution {//排序字符串解法,利用哈希表存储分类后的字符串 +// //创建一个 Map 哈希表存储 分类结果 +// //每次遍历strs,将其转化为字符数组再排序,判断排序好的作为key查询是否存在在hash表中 +// //存在即添加到value-List中,不存在则将该key值与value存进去 +// // 时间复杂度:O(NKlogK),其中 N 是 strs 的长度,而 K 是 strs 中字符串的最大长度。当我们遍历每个字符串时,外部循环具有的复杂度为 O(N)。然后,我们在 O(KlogK) 的时间内对每个字符串排序。 + +// // 空间复杂度:O(NK),排序存储在 res 中的全部信息内容。 +// public List> groupAnagrams(String[] strs) { +// if (strs.length == 0) return new ArrayList<>(); +// Map res = new HashMap(); +// for (String s : strs) { +// char[] ch = s.toCharArray(); +// Arrays.sort(ch); +// String key = String.valueOf(ch);//将字符数组转化为字符串 +// if (!res.containsKey(key)){ +// res.put(key, new ArrayList()); +// } +// res.get(key).add(s); +// } +// return new ArrayList(res.values()); +// } +// } + + +// class Solution {//暴力法 +// //遍历每个元素 与其后面元素比较,如果相等就加入一个List,最后一起加入string[][]中 +// //再继续访问下一个元素 +// //创建一个辅助boolean类型数组,用来判断元素是否已经访问过 +// public List> groupAnagrams(String[] strs) { +// List> res = new ArrayList<>();//创建结果数组 +// boolean[] used = new boolean[strs.length]; +// for (int i = 0; i < strs.length; i++) { +// List temp = null; +// if (!used[i]) { +// temp = new ArrayList(); +// temp.add(strs[i]); +// for (int j = i+1; j < strs.length; j++) { +// if (!used[j] && equals(strs[i], strs[j]) ) { +// temp.add(strs[j]); +// used[j] = true; +// } +// } +// } +// if (temp != null) res.add(temp); +// used[i] = true; +// } +// return res; +// } +// public boolean equals(String s1, String s2) { +// if(s1.length() != s2.length()) return false; +// int[] alphabet = new int[26]; +// for (char ch : s1.toCharArray()) { +// alphabet[ch - 'a']++; +// } +// for (char ch : s2.toCharArray()) { +// alphabet[ch - 'a']--; +// if (alphabet [ch - 'a'] < 0) return false; +// } +// return true; +// } +// } \ No newline at end of file diff --git a/Week_02/README.md b/Week_02/README.md index 50de3041..68acf2a6 100644 --- a/Week_02/README.md +++ b/Week_02/README.md @@ -1 +1,24 @@ -学习笔记 \ No newline at end of file +2020/10/11 学习笔记 + +哈希的概念 + hash算法的概念 Hash: 一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 + +学习到的一些函数新方法 + Arrays.sort(char[] ch);//将ch字符数组按照字母顺序排序 + Arrays.equals(char[] ch1, char[] ch2);//比较两个字符数组是否相等 + Integer.MAX_VALUE代表int的最大值,当常数使用 + Integer.MIN_VALUE代表int的最小值 + Integer类型对象 比较值用"equals", 比较 引用 用"==" + System.arraycopy(nums1, 0, nums_copy, 0, m);//nums1从0开始拷贝到nums_copy从0开始长度为m +树的一些相关概念 + 链表是特殊的树,树是特殊的图(无环) + 前序:根-左-右 + 中序:左-根-右 + 后序:左-右-根 + 二叉搜索树-中序遍历:升序排列 +树的面试题解法一般都是递归,为什么? + 1.该问题可以被分解成若干个重复的子问题; + 2.该问题与它分解出的子问题可以使用相同的算法来解决; + 3.有明确的终止条件 树这种数据结构的特点和上述三个特点高度一致,一棵树的每个非叶子节点的子节点也都是一棵树,都是树自然可以使用相同的算法来处理,因为没有环所以天然具有终止条件。 + 4.另外一方面,树本身是一种非线性的数据结构,循环遍历不易。当然循环遍历也是可以做,树是一种特殊的图,我们完全可以使用图的广度优先遍历算法一层一层的循环遍历整棵树。 + 综上,我们一般还是选择递归的方式来解决树的问题。 \ No newline at end of file diff --git a/Week_02/TwoSum.java b/Week_02/TwoSum.java new file mode 100644 index 00000000..b67bbf21 --- /dev/null +++ b/Week_02/TwoSum.java @@ -0,0 +1,46 @@ +// 已知每种输入只会对应一个答案 + +//方法一 O(n^2) 暴力法 nums[i] + nums[j] == target +//方法二 两遍哈希表 +//方法三 一遍哈希表 + + +class Solution { + // public int[] twoSum2(int[] nums, int target) {//两遍哈希法 + // //将所有值 以及下标存入哈希表中 + // //再次遍历,判断是否存在 key 值为 target-num[i] 且 value值不等于本身的i的元素 + // //如果有相同key值的元素,后面会取代前面的,多个重复元素时,最后结果会输出最前面与最后面的元素下标 + // Map res = new HashMap<>(); + // for (int i = 0; i < nums.length; i++) res.put(nums[i], i); + // for (int i = 0; i < nums.length; i++) { + // if (res.containsKey(target - nums[i]) && res.get(target - nums[i]) != i) + // return new int[]{i, res.get(target-nums[i])}; + // } + // return new int[0]; + // } + + public int[] twoSum(int[] nums, int target) {//一遍哈希法 + //遍历数组 每次哈希查询是否存在这样的 key 值= target - num[i], 有就说明找到目标值了 + //返回 new int {hash.get(target-num[i]),i}; + //否则 将num[i]的值 以及下标 i 存入哈希表中 + Map res = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + if (res.containsKey(target - nums[i])) + return new int[] {res.get(target-nums[i]), i}; + res.put(nums[i], i); + } + return new int[0]; + } + + // public int[] twoSum1(int[] nums, int target) {//暴力法 + // for (int i = 0; i < nums.length-1; i++) { + // for (int j = i + 1; j < nums.length; j++) { + // if (nums[i] + nums[j] == target) { + // return new int[]{i,j}; + // } + // } + // } + // return null; + // } + +} \ No newline at end of file diff --git a/Week_02/ValidAnagram.java b/Week_02/ValidAnagram.java new file mode 100644 index 00000000..01c3f1c1 --- /dev/null +++ b/Week_02/ValidAnagram.java @@ -0,0 +1,26 @@ +class Solution { + public boolean isAnagram1(String s, String t) {//方法一利用(哈希)辅助数组 O(n) O(1) + //遍历s,将每个出现过的元素在对应辅助数组中++ + //遍历t,将每个出现过的元素在对应辅助数组置--,如果有某个元素小于0就返回false + //返回true + //hash算法的概念 Hash: 一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。 ... 简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 + if(s.length() != t.length()) return false; + int[] hash = new int[26]; + for (char ch : s.toCharArray()) { + hash[ch - 'a']++; + } + for (char ch : t.toCharArray()) { + hash[ch - 'a']--; + if(hash[ch - 'a'] < 0) return false; + } + return true; + } + public boolean isAnagram(String s, String t) {//方法二 排序 O(nlogn) O(1)n为s的长度 + //将两个字符串排序,再进行比较equals + char[] s1 = s.toCharArray(); + char[] t1 = t.toCharArray(); + Arrays.sort(s1); + Arrays.sort(t1); + return Arrays.equals(s1,t1); + } +} \ No newline at end of file From 53527e80b0b9d1d0da50b47b242cc69fdcd51bcb Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Mon, 12 Oct 2020 20:53:37 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8F=90=E4=BA=A43.0?= =?UTF-8?q?=20=E8=A1=A5=E5=85=A8=E4=B8=80=E4=BA=9B=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Week_01/Merge Two Sorted Lists.java | 37 --- Week_01/Min Stack.java | 102 -------- Week_01/Move Zeroes.java | 33 --- Week_01/MyDeque.java | 2 +- ...25\260\344\271\213\345\222\214TwoSum.java" | 46 ++++ .../\345\212\240\344\270\200PlusOne.java" | 25 ++ ...\225\260\347\273\204MergeSortedArray.java" | 50 ++++ ...3\276\350\241\250MergeTwoSortedLists.java" | 51 ++++ ...233\250\346\260\264TrappingRainWater.java" | 154 +++++++++++ ...4\346\225\260\347\273\204RotateArray.java" | 64 +++++ ...\200\345\260\217\346\240\210MinStack.java" | 239 ++++++++++++++++++ ...73\345\212\250\351\233\266MoveZeroes.java" | 29 +++ ...0\237\345\210\227DesignCircularDeque.java" | 90 +++++++ Week_02/README.md | 5 +- 14 files changed, 753 insertions(+), 174 deletions(-) delete mode 100644 Week_01/Merge Two Sorted Lists.java delete mode 100644 Week_01/Min Stack.java delete mode 100644 Week_01/Move Zeroes.java create mode 100644 "Week_01/\344\270\244\346\225\260\344\271\213\345\222\214TwoSum.java" create mode 100644 "Week_01/\345\212\240\344\270\200PlusOne.java" create mode 100644 "Week_01/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204MergeSortedArray.java" create mode 100644 "Week_01/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250MergeTwoSortedLists.java" create mode 100644 "Week_01/\346\216\245\351\233\250\346\260\264TrappingRainWater.java" create mode 100644 "Week_01/\346\227\213\350\275\254\346\225\260\347\273\204RotateArray.java" create mode 100644 "Week_01/\346\234\200\345\260\217\346\240\210MinStack.java" create mode 100644 "Week_01/\347\247\273\345\212\250\351\233\266MoveZeroes.java" create mode 100644 "Week_01/\350\256\276\350\256\241\345\276\252\347\216\257\345\217\214\347\253\257\351\230\237\345\210\227DesignCircularDeque.java" diff --git a/Week_01/Merge Two Sorted Lists.java b/Week_01/Merge Two Sorted Lists.java deleted file mode 100644 index 5e5ed6bd..00000000 --- a/Week_01/Merge Two Sorted Lists.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode() {} - * ListNode(int val) { this.val = val; } - * ListNode(int val, ListNode next) { this.val = val; this.next = next; } - * } - */ - //方法遍历依次比较大小插入,直到有一条遍历完 - -class Solution { - public ListNode mergeTwoLists(ListNode l1, ListNode l2) { - ListNode l = new ListNode(); - ListNode p1 = l1, p2 = l2; - ListNode cur = l; - while (p1 != null && p2 != null) { - if (p1.val <= p2.val) { - cur.next = p1; - p1 = p1.next; - cur = cur.next; - } else { - cur.next = p2; - p2 = p2.next; - cur = cur.next; - } - } - if(p1 == null) { - cur.next = p2; - } - if(p2 == null) { - cur.next = p1; - } - return l.next; - } -} \ No newline at end of file diff --git a/Week_01/Min Stack.java b/Week_01/Min Stack.java deleted file mode 100644 index e6df2e5d..00000000 --- a/Week_01/Min Stack.java +++ /dev/null @@ -1,102 +0,0 @@ -//方法一 利用数组模拟栈实现 -//方法二 利用栈与辅助栈实现 -//方法三 利用链表模拟栈实现 - -// class MinStack { -// //方法一 -// int[] min;//存储每次最小值 -// int[] stack; -// int head; -// /** initialize your data structure here. */ -// public MinStack() { -// stack = new int[10000]; -// min = new int[10000]; -// head = 0; -// } - -// public void push(int x) { -// if (head < stack.length) { -// stack[head] = x; -// if(head == 0 || min[head-1] > x) -// min[head] = x; -// else -// min[head] = min[head-1]; -// head++; -// } -// // System.out.print(head); -// } - -// public void pop() { -// if(head > 0) -// head--; -// } - -// public int top() { -// if(head > 0) -// return stack[head-1]; -// else -// return stack[0]; -// } - -// public int getMin() { -// // int min = stack[0]; -// // for(int i = 0 ; i < head; i++) { -// // if(min > stack[i]) -// // min = stack[i]; -// // } -// if(head > 0) -// return min[head-1]; -// else -// return min[head]; -// } - - -// } - -class MinStack { - private Node head; - - public void push(int x) { - if(head == null) - head = new Node(x, x); - else - head = new Node(x, Math.min(x, head.min), head); - } - - public void pop() { - head = head.next; - } - - public int top() { - return head.val; - } - - public int getMin() { - return head.min; - } - - private class Node { - int val; - int min; - Node next; - - private Node(int val, int min) { - this(val, min, null); - } - - private Node(int val, int min, Node next) { - this.val = val; - this.min = min; - this.next = next; - } - } -} - -/** - * Your MinStack object will be instantiated and called as such: - * MinStack obj = new MinStack(); - * obj.push(x); - * obj.pop(); - * int param_3 = obj.top(); - * int param_4 = obj.getMin(); - */ \ No newline at end of file diff --git a/Week_01/Move Zeroes.java b/Week_01/Move Zeroes.java deleted file mode 100644 index 444fc849..00000000 --- a/Week_01/Move Zeroes.java +++ /dev/null @@ -1,33 +0,0 @@ -class Solution { - // public void moveZeroes(int[] nums) { - // int j = 0; - // for (int i = 0; i < nums.length; i++) { - // if (nums[i] != 0) { - // nums[j] = nums[i]; - // if(i != j){ - // nums[i] = 0; - // } - // j++; - // } - // } - // } - //暴力法o(n*n) - //双指针 - public void moveZeroes(int[] nums) { - for (int i = 0,j = 0; j < nums.length ; j++) { - if(nums[j] != 0) { - nums[i] = nums[j]; - if(i != j){ - nums[j] = 0; - } - i++; - } - - } - - } -} -//方法一 挨着挨着移动 -//方法二 开新数组记录零点的位置,再操作原数组,最后补零 -//***方法三 index增加一个j来记录下一个非零元素位置,遇到非零元素交换元素,一次遍历即可 -//***方法四 两次遍历,第一次把所有非零元素移到规定位置,第二次遍历把剩下的元素置零 \ No newline at end of file diff --git a/Week_01/MyDeque.java b/Week_01/MyDeque.java index 587f4e02..0a2c68b6 100644 --- a/Week_01/MyDeque.java +++ b/Week_01/MyDeque.java @@ -2,7 +2,7 @@ import java.util.LinkedList; public class MyDeque { - public static void main(String[] args) { + public static void main(String[] args) {//改写Deque Deque deque = new LinkedList(); deque.offerFirst("a"); deque.offerFirst("b"); diff --git "a/Week_01/\344\270\244\346\225\260\344\271\213\345\222\214TwoSum.java" "b/Week_01/\344\270\244\346\225\260\344\271\213\345\222\214TwoSum.java" new file mode 100644 index 00000000..b67bbf21 --- /dev/null +++ "b/Week_01/\344\270\244\346\225\260\344\271\213\345\222\214TwoSum.java" @@ -0,0 +1,46 @@ +// 已知每种输入只会对应一个答案 + +//方法一 O(n^2) 暴力法 nums[i] + nums[j] == target +//方法二 两遍哈希表 +//方法三 一遍哈希表 + + +class Solution { + // public int[] twoSum2(int[] nums, int target) {//两遍哈希法 + // //将所有值 以及下标存入哈希表中 + // //再次遍历,判断是否存在 key 值为 target-num[i] 且 value值不等于本身的i的元素 + // //如果有相同key值的元素,后面会取代前面的,多个重复元素时,最后结果会输出最前面与最后面的元素下标 + // Map res = new HashMap<>(); + // for (int i = 0; i < nums.length; i++) res.put(nums[i], i); + // for (int i = 0; i < nums.length; i++) { + // if (res.containsKey(target - nums[i]) && res.get(target - nums[i]) != i) + // return new int[]{i, res.get(target-nums[i])}; + // } + // return new int[0]; + // } + + public int[] twoSum(int[] nums, int target) {//一遍哈希法 + //遍历数组 每次哈希查询是否存在这样的 key 值= target - num[i], 有就说明找到目标值了 + //返回 new int {hash.get(target-num[i]),i}; + //否则 将num[i]的值 以及下标 i 存入哈希表中 + Map res = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + if (res.containsKey(target - nums[i])) + return new int[] {res.get(target-nums[i]), i}; + res.put(nums[i], i); + } + return new int[0]; + } + + // public int[] twoSum1(int[] nums, int target) {//暴力法 + // for (int i = 0; i < nums.length-1; i++) { + // for (int j = i + 1; j < nums.length; j++) { + // if (nums[i] + nums[j] == target) { + // return new int[]{i,j}; + // } + // } + // } + // return null; + // } + +} \ No newline at end of file diff --git "a/Week_01/\345\212\240\344\270\200PlusOne.java" "b/Week_01/\345\212\240\344\270\200PlusOne.java" new file mode 100644 index 00000000..b0e80129 --- /dev/null +++ "b/Week_01/\345\212\240\344\270\200PlusOne.java" @@ -0,0 +1,25 @@ +//普通情况直接digits[digits.length-1]++即可 +//当为 19,29,39,等等时上一位也需要加一 +//当为 9 , 99, 999 等等时需要进位,以前的数组将不够用 + +//模拟操作,从最后一位加起,直至上一位没有9 + +class Solution { + public int[] plusOne(int[] digits) { + int i = digits.length-1; + while (i >= 0) { + if(digits[i] == 9) + digits[i] = 0; + else { + digits[i]++; + break;//优化为 return digits; + } + i--; + } + if (i < 0) {//优化后 可以忽略此if判断 + digits = new int[digits.length+1]; + digits[0] = 1; + } + return digits; + } +} \ No newline at end of file diff --git "a/Week_01/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204MergeSortedArray.java" "b/Week_01/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204MergeSortedArray.java" new file mode 100644 index 00000000..b42abbb9 --- /dev/null +++ "b/Week_01/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204MergeSortedArray.java" @@ -0,0 +1,50 @@ +class Solution { + public void merge(int[] nums1, int m, int[] nums2, int n) {//方法三 尾部插法,双指针 + //从nums1尾部开始,i指针指向m-1,j指针指向n-1,从尾部插入,这样不用担心覆盖到nums1的元素 + int i = m - 1, j = n - 1; + for( ; i >= 0 && j >= 0; ) { + if (nums1[i] <= nums2[j]) nums1[i + j + 1] = nums2[j--]; + else nums1[i + j + 1] = nums1[i--]; + } + while (j >= 0) { + nums1[i + j + 1] = nums2[j--]; + } + } + + public void merge2(int[] nums1, int m, int[] nums2, int n) {//方法二 额外数组O(m+n) O(m+n) + { + // int[] nums = new int[m+n]; + // int i = 0, j = 0; + // while (i < m && j < n) { + // if (nums1[i] < nums2[j]) nums[i+j] = nums1[i++]; + // else nums[i+j] = nums2[j++]; + // } + // while (i < m) { + // nums[i+j] = nums1[i++]; + // } + // while (j < n) { + // nums[i+j] = nums2[j++]; + // } + // for (int k = 0; k < m+n; k++) + // nums1[k] = nums[k]; + } + //优化版 O(m+n) O(m) + int[] nums1_copy = new int[m]; + System.arraycopy(nums1, 0, nums1_copy, 0, m);//nums1从0开始拷贝到nums1_copy从0开始长度为m + int i = 0, j = 0; + while (i < m && j < n) { + if (nums1_copy[i] < nums2[j]) nums1[i+j] = nums1_copy[i++]; + else nums1[i+j] = nums2[j++]; + } + if (i < m) System.arraycopy(nums1_copy, i, nums1, i + j, m + n - i - j); + if (j < n) System.arraycopy(nums2, j, nums1, i + j, m + n - i -j); + } + + public void merge1(int[] nums1, int m, int[] nums2, int n) {//方法一 直接nums2插入到num1尾部,再sort + //O(mlogm) O(1) + for (int i = 0; i < n; i++) + nums1[m+i] = nums2[i]; + Arrays.sort(nums1); + } + +} \ No newline at end of file diff --git "a/Week_01/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250MergeTwoSortedLists.java" "b/Week_01/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250MergeTwoSortedLists.java" new file mode 100644 index 00000000..5372c8ec --- /dev/null +++ "b/Week_01/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250MergeTwoSortedLists.java" @@ -0,0 +1,51 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +class Solution { + public ListNode mergeTwoLists(ListNode l1, ListNode l2) {//方法二 递归解法 O(m+n) l1l2元素个数 + //通过递归找到最小的值,然后依次返回作为上一个节点的next + if (l1 == null) + return l2; + else if (l2 == null) + return l1; + else if (l1.val < l2.val) { + l1.next = mergeTwoLists(l1.next, l2); + return l1; + } else { + l2.next = mergeTwoLists(l1, l2.next); + return l2; + } + } + public ListNode mergeTwoLists1(ListNode l1, ListNode l2) {//方法一 一般解法 + //方法一 构建一个新的节点,一边遍历一边比较,小的插入节点 + //如果有某一条遍历完直接插入尾部不在比较 + ListNode head = new ListNode(); + ListNode temp = head; + while (l1 != null && l2 != null) { + if(l1.val < l2.val) { + temp.next = l1; + l1 = l1.next; + temp = temp.next; + } + else { + temp.next = l2; + l2 = l2.next; + temp = temp.next; + } + } + if(l1 == null) + temp.next = l2; + if(l2 == null) + temp.next = l1; + return head.next; + } +} \ No newline at end of file diff --git "a/Week_01/\346\216\245\351\233\250\346\260\264TrappingRainWater.java" "b/Week_01/\346\216\245\351\233\250\346\260\264TrappingRainWater.java" new file mode 100644 index 00000000..9d33bfb9 --- /dev/null +++ "b/Week_01/\346\216\245\351\233\250\346\260\264TrappingRainWater.java" @@ -0,0 +1,154 @@ +//方法一 按行求 +//方法二 按列求 +//方法三 动态规划 +//方法四 双指针 +//方法五 栈 +//方法六 固定最高的柱子,左右双指针夹逼法 +//方法七 数学解法 +class Solution { + public int trap(int[] height) { //方法七 数学解法 + //从左到右遍历出最高左边高度 + //以及从右遍历出最高右边高度 + //减去柱子的高度 + int max_left = -1, max_right = -1; + int sum = 0, sum1 = 0, sum2 = 0; + int len = height.length; + // int sum3 = 0; + + for (int i = 0; i < len; i++) { + if(height[i] > max_left) + max_left = height[i]; + if(height[len-i-1] > max_right) + max_right = height[len - i - 1]; + sum1 += max_left; + sum2 += max_right; + sum -= height[i]; + } + sum += sum1 + sum2 - max_left * len; + return sum; + } + public int trap6(int[] height) { //方法六 固定最高柱子 + int max_height = -1; + int max_index = 0; + int sum = 0, max_left = 0, max_right = 0; + for (int i = 0; i < height.length; i++) { + if (height[i] > max_height) { + max_height = height[i]; + max_index = i; + } + } + for (int i = 0 ; i < max_index; i++) { + if (height[i] > max_left) + max_left = height[i]; + else + sum += max_left - height[i]; + } + for (int i = height.length-1; i > max_index; i--) { + if (height[i] > max_right) + max_right = height[i]; + else + sum += max_right - height[i]; + } + return sum; + } + public int trap5(int[] height) { //方法五 栈 + //创建一个栈,只要有比当前栈顶小或相等的就入栈,当遇见比栈顶大的时就说明可以确定中间的水量了 + //栈不为空且大于栈顶元素才可以开始出栈 + //如果出栈后栈空了就不用继续计算雨量了 + Stack stack = new Stack<>(); + int sum = 0; + for (int i = 0; i < height.length; i++) { + while (!stack.empty() && height[i] > height[stack.peek()]) { + int h = stack.pop(); + if(stack.empty()) + break; + int distance = i - stack.peek() - 1; + int min = Math.min(height[i], height[stack.peek()]); + sum += distance * (min - height[h]); + } + stack.push(i); + } + return sum; + } + public int trap4(int[] height) { //方法四 双指针 O(n) O(1) 通过判断max_left与max_right来改变遍历顺序 + //与动态规划类似,不过进行优化,这样在遍历的时候更新max_left与max_right + //省去了O(n)的空间 + int sum = 0; + int max_left = -1, max_right = -1; + int left = 1, right = height.length - 2; + while (left <= right) { + if(height[left-1] < height[right+1]) { + max_left = Math.max(max_left, height[left-1]); + if (max_left > height[left]) + sum += max_left - height[left]; + left++; + } else { + max_right = Math.max(max_right, height[right+1]); + if (max_right > height[right]) + sum += max_right - height[right]; + right--; + } + } + return sum; + } + public int trap3(int[] height) { //方法三 动态规划 O(n) O(n) + //我们发现按列求每次遍历左右最大值有些耗费时间,可以利用一个数组存储当前的最大值,避免重复操作 + int[] max_left = new int[height.length]; + int[] max_right = new int[height.length]; + int sum = 0; + for (int i = 1; i < height.length; i++) + max_left[i] = Math.max(max_left[i-1], height[i-1]); + for (int i = height.length - 2; i >= 0; i--) + max_right[i] = Math.max(max_right[i+1], height[i+1]); + for (int i = 1; i < height.length; i++) { + int min = max_left[i] < max_right[i] ? max_left[i] : max_right[i]; + if(min > height[i]) + sum += min - height[i]; + } + return sum; + } + + public int trap2(int[] height) { //方法二 按列求 O(n^2) + //从第1列开始直到length-2列结束,因为第0列和length-1列不可能存有雨水 + //每次遍历找出左边最高以及右边最高的的 + //取min 雨水量 += min - height[i] + int sum = 0; + for (int i = 1; i < height.length - 1; i++) { + int left_max = -1; + for (int k = i - 1; k >= 0; k--) + left_max = Math.max(left_max, height[k]); + int right_max = -1; + for (int k = i + 1; k < height.length; k++) + right_max = Math.max(right_max, height[k]); + int min = left_max < right_max ? left_max : right_max; + if(min > height[i]) + sum += min - height[i]; + } + return sum; + } + + public int trap1(int[] height) { //方法一 按行求 O(m*n) m为最大高度 + //找出最大高度,根据最大高度确定遍历层数 + //从第一层水开始 + //如果有start && height[j] < i ,temp++ + //如果有height[j] >= i ,开始计数 start = true, sum += temp, temp = 0 + int max_height = -1; + int sum = 0; + for (int i = 0; i < height.length; i++) + max_height = Math.max(max_height, height[i]); + for (int i = 1; i <= max_height; i++) { //i代表雨的层数 + boolean start = false; + int temp = 0; + for (int j = 0; j < height.length; j++) { + if (start && height[j] < i) + temp++; + if (height[j] >= i) { + start = true; + sum += temp; + temp = 0; + } + } + } + return sum; + } +} \ No newline at end of file diff --git "a/Week_01/\346\227\213\350\275\254\346\225\260\347\273\204RotateArray.java" "b/Week_01/\346\227\213\350\275\254\346\225\260\347\273\204RotateArray.java" new file mode 100644 index 00000000..03fa78e2 --- /dev/null +++ "b/Week_01/\346\227\213\350\275\254\346\225\260\347\273\204RotateArray.java" @@ -0,0 +1,64 @@ +//方法二 创建一个新的数组,将移动后的位置拷贝到新的数组(不符合题意,空间复杂度超标) + +class Solution { + public void rotate(int[] nums, int k) {//方法四 模拟换座位,每次移动一个元素,一直换到与开始的位置重复,移动下一个元素 + //首先k %= len; + //首先从0号元素开始,它将移到k下标的位置,而k号元素将移到2k%len下标位置 + //直至等于0下标或者已经移动n个元素了 + //若等于0下标,则从1号元素开始,依次类推 + int len = nums.length; + k %= len; + int count = 0;//计数,移动了多少个元素 + for (int i = 0; count < len; i++) { + { //逻辑一 是每次先找到下一位置,直到要换的位置已经是之前找到过的位置了 + // int next = (i + k) % len; + // int outseat = nums[i]; + // do{ + // int temp = nums[next]; + // nums[next] = outseat; + // outseat = temp; + // next = (next + k) % len; + // count++; + // }while(next != (i + k) % len); + } + //逻辑二 找到当前位置,与下一位置交换,直到当前位置已经被交换过 + int cur = i; + int outseat = nums[i]; + do { + int next = (cur + k) % len; + int temp = nums[next]; + nums[next] = outseat; + outseat = temp; + cur = next; + count ++; + } while(cur != i); + } + } + + public void rotate3(int[] nums, int k) {//方法三 三次翻转,逆转所有元素,逆转前k个, 再逆转后n-k个 + int len = nums.length; + k %= len; + reverse2(nums, 0, len-1); + reverse2(nums, 0, k-1); + reverse2(nums, k, len-1); + } + public void reverse2(int[]nums, int start, int end) { + while (start < end) { + int temp = nums[start]; + nums[start] = nums[end]; + nums[end] = temp; + start++; + end--; + } + } + + public void rotate1(int[] nums, int k) {//方法一 暴力法 一次移动一位,移动k次 O(KN) + int len = nums.length; + for (int i = 0; i < k; i++) { + int temp = nums[len-1]; + for(int j = len-1; j > 0; j--) + nums[j] = nums[j-1]; + nums[0] = temp; + } + } +} \ No newline at end of file diff --git "a/Week_01/\346\234\200\345\260\217\346\240\210MinStack.java" "b/Week_01/\346\234\200\345\260\217\346\240\210MinStack.java" new file mode 100644 index 00000000..5c4608d7 --- /dev/null +++ "b/Week_01/\346\234\200\345\260\217\346\240\210MinStack.java" @@ -0,0 +1,239 @@ +//方法一 利用数组模拟栈实现 +//方法二 利用栈与辅助栈实现 +//方法三 利用链表模拟栈实现 + +// class MinStack { +// //方法一 +// int[] min;//存储每次最小值 +// int[] stack; +// int head; +// /** initialize your data structure here. */ +// public MinStack() { +// stack = new int[10000]; +// min = new int[10000]; +// head = 0; +// }//方法一 用已存在的栈类 实现 +//方法二 用数组实现(不推荐,不能动态处理问题) +//方法三 用链表实现 +class MinStack { + //用链表 + class Node { + int val; + int min; + Node next; + public Node(int val, int min, Node next) { + this.val = val; + this.min = min; + this.next = next; + } + } + Node head; + public MinStack() { + } + + public void push(int x) { + if (head != null) + head = new Node(x, Math.min(x, head.min), head); + else + head = new Node(x, x, null); + } + + public void pop() { + head = head.next; + } + + public int top() { + return head.val; + } + + public int getMin() { + return head.min; + } +} + +// class MinStack { +// //用java内置的stack实现 +// //且辅助栈与数据栈不同步(可以节约一些空间) +// Stack data; +// Stack helper; +// public MinStack() { +// data = new Stack(); +// helper = new Stack(); +// } + +// public void push(int x) { +// data.push(x); +// if (helper.empty() || x <= helper.peek()) +// helper.push(x); +// } + +// public void pop() { +// // int x = data.pop(); +// // if (x == helper.peek()) +// // helper.pop(); +// Integer x = data.pop(); +// if (x.equals(helper.peek())) +// helper.pop(); +// } + +// public int top() { +// return data.peek(); +// } + +// public int getMin() { +// return helper.peek(); +// } +// } + + +// class MinStack { +// //用已有的栈实现 且辅助栈与数据栈同步 +// Stack stack; +// Stack minStack; +// /** initialize your data structure here. */ +// public MinStack() { +// stack = new Stack(); +// minStack = new Stack(); +// } + +// public void push(int x) { +// stack.push(x); +// if (minStack.empty() || x <= minStack.peek()) { +// minStack.push(x); +// } else { +// minStack.push(minStack.peek()); +// } +// } + +// public void pop() { +// stack.pop(); +// minStack.pop(); +// } + +// public int top() { +// return stack.peek(); +// } + +// public int getMin() { +// return minStack.peek(); +// } +// } +// class MinStack { + +// /** initialize your data structure here. */ +// public MinStack() { + +// } + +// public void push(int x) { + +// } + +// public void pop() { + +// } + +// public int top() { + +// } + +// public int getMin() { + +// } +// } + +/** + * Your MinStack object will be instantiated and called as such: + * MinStack obj = new MinStack(); + * obj.push(x); + * obj.pop(); + * int param_3 = obj.top(); + * int param_4 = obj.getMin(); + */ + +// public void push(int x) { +// if (head < stack.length) { +// stack[head] = x; +// if(head == 0 || min[head-1] > x) +// min[head] = x; +// else +// min[head] = min[head-1]; +// head++; +// } +// // System.out.print(head); +// } + +// public void pop() { +// if(head > 0) +// head--; +// } + +// public int top() { +// if(head > 0) +// return stack[head-1]; +// else +// return stack[0]; +// } + +// public int getMin() { +// // int min = stack[0]; +// // for(int i = 0 ; i < head; i++) { +// // if(min > stack[i]) +// // min = stack[i]; +// // } +// if(head > 0) +// return min[head-1]; +// else +// return min[head]; +// } + + +// } + +class MinStack { + private Node head; + + public void push(int x) { + if(head == null) + head = new Node(x, x); + else + head = new Node(x, Math.min(x, head.min), head); + } + + public void pop() { + head = head.next; + } + + public int top() { + return head.val; + } + + public int getMin() { + return head.min; + } + + private class Node { + int val; + int min; + Node next; + + private Node(int val, int min) { + this(val, min, null); + } + + private Node(int val, int min, Node next) { + this.val = val; + this.min = min; + this.next = next; + } + } +} + +/** + * Your MinStack object will be instantiated and called as such: + * MinStack obj = new MinStack(); + * obj.push(x); + * obj.pop(); + * int param_3 = obj.top(); + * int param_4 = obj.getMin(); + */ \ No newline at end of file diff --git "a/Week_01/\347\247\273\345\212\250\351\233\266MoveZeroes.java" "b/Week_01/\347\247\273\345\212\250\351\233\266MoveZeroes.java" new file mode 100644 index 00000000..bcb2abc8 --- /dev/null +++ "b/Week_01/\347\247\273\345\212\250\351\233\266MoveZeroes.java" @@ -0,0 +1,29 @@ +//方法一 暴力法 挨着挨着移动 +//方法二 交换法 双指针,cur指向当前非零位置,i遍历,如果当前有非零元素那么就放到cur位置,当前元素变成0,cur++,i继续++ +//方法三 两次遍历法 第一次把所有非零元素移到规定位置,第二次遍历把剩下的元素置零 + +class Solution { + // public void moveZeroes(int[] nums) { + // int cur = 0; + // for (int i = 0; i < nums.length; i++) { + // if(nums[i] != 0) { + // nums[cur] = nums[i]; + // if(i != cur) {//简化交换,同时避免一开始ij相等时被置为0 + // nums[i] = 0; + // } + // cur++; + // } + // } + // } + public void moveZeroes(int[] nums) {//方法三 + int cur = 0; + for (int i = 0; i < nums.length; i++) { + if(nums[i] != 0) { + nums[cur++] = nums[i]; + } + } + while(cur < nums.length) { + nums[cur++] = 0; + } + } +} \ No newline at end of file diff --git "a/Week_01/\350\256\276\350\256\241\345\276\252\347\216\257\345\217\214\347\253\257\351\230\237\345\210\227DesignCircularDeque.java" "b/Week_01/\350\256\276\350\256\241\345\276\252\347\216\257\345\217\214\347\253\257\351\230\237\345\210\227DesignCircularDeque.java" new file mode 100644 index 00000000..629ec8c6 --- /dev/null +++ "b/Week_01/\350\256\276\350\256\241\345\276\252\347\216\257\345\217\214\347\253\257\351\230\237\345\210\227DesignCircularDeque.java" @@ -0,0 +1,90 @@ +//方法一 利用数组实现 +//方法二 利用循环双向链表实现 + +class MyCircularDeque { + + int[] cirdeque; + int head, tail, size; + /** Initialize your data structure here. Set the size of the deque to be k. */ + public MyCircularDeque(int k) { + size = k+1; + cirdeque = new int[size]; + head = 0; + tail = 0; + } + + /** Adds an item at the front of Deque. Return true if the operation is successful. */ + public boolean insertFront(int value) { + if (isFull()) { + return false; + } else { + head = (head - 1 + size) % size; + cirdeque[head] = value; + return true; + } + } + + /** Adds an item at the rear of Deque. Return true if the operation is successful. */ + public boolean insertLast(int value) { + if (isFull()) { + return false; + } else { + cirdeque[tail] = value; + tail = (tail + 1) % size; + return true; + } + } + + /** Deletes an item from the front of Deque. Return true if the operation is successful. */ + public boolean deleteFront() { + if (isEmpty()) { + return false; + } else { + head = (head + 1) % size; + return true; + } + } + + /** Deletes an item from the rear of Deque. Return true if the operation is successful. */ + public boolean deleteLast() { + if (isEmpty()) { + return false; + } else { + tail = (tail - 1 + size) % size; + return true; + } + } + + /** Get the front item from the deque. */ + public int getFront() { + return isEmpty() ? -1 : cirdeque[head]; + } + + /** Get the last item from the deque. */ + public int getRear() { + return isEmpty() ? -1 : cirdeque[(tail - 1 + size) % size]; + } + + /** Checks whether the circular deque is empty or not. */ + public boolean isEmpty() { + return head == tail; + } + + /** Checks whether the circular deque is full or not. */ + public boolean isFull() { + return head == (tail + 1) % size; + } +} + +/** + * Your MyCircularDeque object will be instantiated and called as such: + * MyCircularDeque obj = new MyCircularDeque(k); + * boolean param_1 = obj.insertFront(value); + * boolean param_2 = obj.insertLast(value); + * boolean param_3 = obj.deleteFront(); + * boolean param_4 = obj.deleteLast(); + * int param_5 = obj.getFront(); + * int param_6 = obj.getRear(); + * boolean param_7 = obj.isEmpty(); + * boolean param_8 = obj.isFull(); + */ \ No newline at end of file diff --git a/Week_02/README.md b/Week_02/README.md index 68acf2a6..fceb7388 100644 --- a/Week_02/README.md +++ b/Week_02/README.md @@ -21,4 +21,7 @@ 2.该问题与它分解出的子问题可以使用相同的算法来解决; 3.有明确的终止条件 树这种数据结构的特点和上述三个特点高度一致,一棵树的每个非叶子节点的子节点也都是一棵树,都是树自然可以使用相同的算法来处理,因为没有环所以天然具有终止条件。 4.另外一方面,树本身是一种非线性的数据结构,循环遍历不易。当然循环遍历也是可以做,树是一种特殊的图,我们完全可以使用图的广度优先遍历算法一层一层的循环遍历整棵树。 - 综上,我们一般还是选择递归的方式来解决树的问题。 \ No newline at end of file + 综上,我们一般还是选择递归的方式来解决树的问题。 +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +学习到的一些新的函数方法或者关键字 + instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:boolean result = obj instanceof Class \ No newline at end of file From 3815f79e1441658a58a57a1d66d5b1d76ceb7dba Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Mon, 12 Oct 2020 21:04:00 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E8=A1=A5=E5=85=852.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...45\216\206N-aryTreePreorderTraversal.java" | 76 ++++++++++ ...25\260\344\271\213\345\222\214TwoSum.java" | 0 ...45\216\206BinaryTreeInorderTraversal.java" | 136 ++++++++++++++++++ ...5\216\206BinaryTreePreorderTraversal.java" | 105 ++++++++++++++ ...345\210\206\347\273\204GroupAnagrams.java" | 0 ...\344\275\215\350\257\215ValidAnagram.java" | 0 6 files changed, 317 insertions(+) create mode 100644 "Week_02/N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206N-aryTreePreorderTraversal.java" rename Week_02/TwoSum.java => "Week_02/\344\270\244\346\225\260\344\271\213\345\222\214TwoSum.java" (100%) create mode 100644 "Week_02/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\255\345\272\217\351\201\215\345\216\206BinaryTreeInorderTraversal.java" create mode 100644 "Week_02/\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206BinaryTreePreorderTraversal.java" rename Week_02/GroupAnagrams.java => "Week_02/\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204GroupAnagrams.java" (100%) rename Week_02/ValidAnagram.java => "Week_02/\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215ValidAnagram.java" (100%) diff --git "a/Week_02/N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206N-aryTreePreorderTraversal.java" "b/Week_02/N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206N-aryTreePreorderTraversal.java" new file mode 100644 index 00000000..b35cfebc --- /dev/null +++ "b/Week_02/N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206N-aryTreePreorderTraversal.java" @@ -0,0 +1,76 @@ +/* +// Definition for a Node. +class Node { + public int val; + public List children; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { + val = _val; + children = _children; + } +}; +*/ + +class Solution { + +LinkedList temp=new LinkedList<>(); + public List preorder(Node root) {//方法二 迭代法 + List res = new ArrayList<>(); + if(root == null) return res; + Deque stk = new ArrayDeque<>(); + stk.push(root); + while(!stk.isEmpty()) { + Node node = stk.pop(); + res.add(node.val); + for(int i = node.children.size() - 1 ; i >= 0 ; i--) + stk.push(node.children.get(i)); + } + return res; + } + + public List preorder_2_1(Node root) {//方法二 迭代法 + List ans = new ArrayList(); + if (root == null) return res; + Deque deque = new ArrayDeque(); + deque.offerLast(root); + while (!deque.isEmpty()) { + Node node = deque.pollLast(); + res.add(node.val); + Collections.reverse(node.children); + for (Node child : node.children) + deque.offerLast(child); + } + return res; + } + + List res = new ArrayList(); + public List preorder_1_2(Node root) {//方法一 递归(不使用辅助函数) + // List res = new ArrayList(); + if(root == null) return res; + res.add(root.val); + for (Node node : root.children) { + // res.addAll(preorder(node)); + preorder(node); + } + return res; + } + + public List preorder_1_1(Node root) {//方法一 递归(使用辅助函数) + List res = new ArrayList(); + helper(root, res); + return res; + } + public void helper(Node root, List res) { + if (root == null) return; + res.add(root.val); + for (Node node : root.children) { + helper(node, res); + } + } +} \ No newline at end of file diff --git a/Week_02/TwoSum.java "b/Week_02/\344\270\244\346\225\260\344\271\213\345\222\214TwoSum.java" similarity index 100% rename from Week_02/TwoSum.java rename to "Week_02/\344\270\244\346\225\260\344\271\213\345\222\214TwoSum.java" diff --git "a/Week_02/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\255\345\272\217\351\201\215\345\216\206BinaryTreeInorderTraversal.java" "b/Week_02/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\255\345\272\217\351\201\215\345\216\206BinaryTreeInorderTraversal.java" new file mode 100644 index 00000000..6d7af91e --- /dev/null +++ "b/Week_02/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\255\345\272\217\351\201\215\345\216\206BinaryTreeInorderTraversal.java" @@ -0,0 +1,136 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List inorderTraversal_4_2(TreeNode root) {//Morris 中序遍历 O(N) O(1) + //破坏法 + List res = new ArrayList(); + TreeNode pre = null; + while(root!=null) { + //如果左节点不为空,就将当前节点连带右子树全部挂到 + //左节点的最右子树下面 + if(root.left!=null) { + pre = root.left; + while(pre.right!=null) { + pre = pre.right; + } + pre.right = root; + //将root指向root的left + TreeNode tmp = root; + root = root.left; + tmp.left = null; + //左子树为空,则打印这个节点,并向右边遍历 + } else { + res.add(root.val); + root = root.right; + } + } + return res; + } + + public List inorderTraversal_4_1(TreeNode root) {//Morris 中序遍历 O(N) O(1) + //完整法 + // 莫里斯遍历的优点是没有使用任何辅助空间。缺点是改变了整个树的结构,强行把一棵二叉树改成一段链表结构。 + List res = new ArrayList(); + TreeNode predecessor = null; + + while (root != null) { + if (root.left != null) { + // predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止 + predecessor = root.left; + while (predecessor.right != null && predecessor.right != root) { + predecessor = predecessor.right; + } + + // 让 predecessor 的右指针指向 root,继续遍历左子树 + if (predecessor.right == null) { + predecessor.right = root; + root = root.left; + } + // 说明左子树已经访问完了,我们需要断开链接 + else { + res.add(root.val); + predecessor.right = null; + root = root.right; + } + } + // 如果没有左孩子,则直接访问右孩子 + else { + res.add(root.val); + root = root.right; + } + } + return res; + } + + public List inorderTraversal(TreeNode root) {//方法三 栈 反序入栈 + //非递归-另一种解法(颜色标记法) 将节点与结点的值一起压入栈,通过判断对象是否为节点类型继续进行操作 + //思路 中序遍历 左根右 入栈顺序 右根左 O(N) O(N) + List res = new ArrayList(); + if(root == null) return res; + Deque stk = new ArrayDeque(); + stk.push(root); + while (!stk.isEmpty()) { + Object o = stk.pop(); + //因为中序遍历是左节点--根节点--右节点 + //即出栈顺序为左节点--根节点--右节点,入栈顺序相反 + if( o instanceof TreeNode) { + TreeNode node = (TreeNode)o; + if(node.right != null) stk.push(node.right); + stk.push(node.val); + if(node.left != null) stk.push(node.left); + } else { + res.add((int)o); + } + } + return res; + } + + public List inorderTraversal_2(TreeNode root) {//方法二 栈 + //思路 手动用栈来模拟 递归方法的程序栈 + //中序遍历 左根右 O(N) O(N) + List res = new ArrayList(); + Deque stk = new ArrayDeque(); + while (root != null || !stk.isEmpty() ) { + //不断往左子树方向走,每走一次就将当前节点保存到栈中 + //这是模拟递归的调用 + while(root != null) { + stk.push(root); + root = root.left; + } + //当前节点为空,说明左边走到头了,从栈中弹出节点并保存 + //然后转向右边节点,继续上面整个过程 + root = stk.pop(); + res.add(root.val); + root = root.right; + } + return res; + } + + public List inorderTraversal_1(TreeNode root) {//方法一 递归解法 + //思路 中序遍历-左根右 时间复杂度 O(n)二叉树的遍历中每个节点会被访问一次且只会被访问一次。 + //空间复杂度 O(n)空间复杂度取决于递归的栈深度,而栈深度在二叉树为一条链的情况下会达到O(n) 的级别。 + List res = new ArrayList(); + if (root == null) return res; + inorder_1(root, res); + return res; + } + public void inorder_1(TreeNode root, List res) { + if (root == null) return; + inorder_1(root.left, res); + res.add(root.val); + inorder_1(root.right, res); + } +} \ No newline at end of file diff --git "a/Week_02/\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206BinaryTreePreorderTraversal.java" "b/Week_02/\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206BinaryTreePreorderTraversal.java" new file mode 100644 index 00000000..857f42df --- /dev/null +++ "b/Week_02/\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206BinaryTreePreorderTraversal.java" @@ -0,0 +1,105 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List postorderTraversal(TreeNode root) {//二叉树的后序遍历 迭代 中序遍历的变形 + List ans = new ArrayList<>(); + Stack stack = new Stack<>(); + while(root != null || !stack.isEmpty()) { + while(root != null) { + stack.add(root); + ans.add(0, root.val); + root = root.right; + } + root = stack.pop(); + root = root.left; + } + + return ans; + } + + public List preorderTraversal_3(TreeNode root) {//方法四 Morris解法 最后会还原树的结构 + List res = new ArrayList(); + if (root == null) { + return res; + } + TreeNode cur1 = root; + TreeNode cur2 = null; + while (cur1 != null) { + cur2 = cur1.left; + if (cur2 != null) { + while (cur2.right != null && cur2.right != cur1) { + cur2 = cur2.right; + } + if (cur2.right == null) { + cur2.right = cur1; + // System.out.print(cur1.value + " "); + res.add(cur1.val); + cur1 = cur1.left; + continue; + } else { + cur2.right = null;//断开连接(伪边) + } + } else { + // System.out.print(cur1.value + " "); + res.add(cur1.val); + } + cur1 = cur1.right; + } + return res; + } + public List preorderTraversal_2_2(TreeNode root) {//方法三 迭代 中序遍历修改版 + Stack stack = new Stack<>(); + List list = new ArrayList<>(); + TreeNode cur = root; + while(!stack.isEmpty() || cur != null){ + while(cur != null){ + list.add(cur.val); + stack.push(cur); + cur = cur.left; + } + cur = stack.pop(); + cur = cur.right; + } + return list; + } + public List preorderTraversal(TreeNode root) {//方法二 栈 + //思路 手动用栈模拟递归中程序栈 + List res = new ArrayList(); + if (root == null) return res; + Deque stk = new ArrayDeque(); + stk.push(root); + while (!stk.isEmpty()) { + TreeNode node = stk.pop(); + res.add(node.val); + if(node.right != null) stk.push(node.right); + if(node.left != null) stk.push(node.left); + } + return res; + } + + public List preorderTraversal_1(TreeNode root) {//方法一 递归 + List res = new ArrayList(); + if (root == null) return res; + preorder(root,res); + return res; + } + public void preorder(TreeNode root, List res) { + if(root == null) return; + res.add(root.val); + preorder(root.left, res); + preorder(root.right, res); + } +} \ No newline at end of file diff --git a/Week_02/GroupAnagrams.java "b/Week_02/\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204GroupAnagrams.java" similarity index 100% rename from Week_02/GroupAnagrams.java rename to "Week_02/\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204GroupAnagrams.java" diff --git a/Week_02/ValidAnagram.java "b/Week_02/\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215ValidAnagram.java" similarity index 100% rename from Week_02/ValidAnagram.java rename to "Week_02/\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215ValidAnagram.java" From d7795fd239d9e3aa68cb524c24eec4c80b08094c Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Tue, 13 Oct 2020 16:09:50 +0800 Subject: [PATCH 07/12] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8F=90=E4=BA=A4=204.?= =?UTF-8?q?0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...216\206N-ary TreeLevelOrderTraversal.java" | 66 +++++++++++ ...4\345\244\215\346\235\202\345\272\246.PNG" | Bin 0 -> 53431 bytes ...\345\217\211\345\240\206MyBinaryHeap.java" | 103 ++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 "Week_02/N\345\217\211\346\240\221\347\232\204\345\261\202\345\272\217\351\201\215\345\216\206N-ary TreeLevelOrderTraversal.java" create mode 100644 "Week_02/\345\220\204\347\247\215\345\240\206\347\232\204\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246.PNG" create mode 100644 "Week_02/\346\211\213\345\212\250\345\256\236\347\216\260\344\272\214\345\217\211\345\240\206MyBinaryHeap.java" diff --git "a/Week_02/N\345\217\211\346\240\221\347\232\204\345\261\202\345\272\217\351\201\215\345\216\206N-ary TreeLevelOrderTraversal.java" "b/Week_02/N\345\217\211\346\240\221\347\232\204\345\261\202\345\272\217\351\201\215\345\216\206N-ary TreeLevelOrderTraversal.java" new file mode 100644 index 00000000..07ac1242 --- /dev/null +++ "b/Week_02/N\345\217\211\346\240\221\347\232\204\345\261\202\345\272\217\351\201\215\345\216\206N-ary TreeLevelOrderTraversal.java" @@ -0,0 +1,66 @@ +/* +// Definition for a Node. +class Node { + public int val; + public List children; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { + val = _val; + children = _children; + } +}; +*/ +//广度优先搜索。我们使用队列来进行广度优先搜索,队列具有先进先出的特性。 +//栈应用于深度优先搜索。 +class Solution { + + public List> levelOrder_2(Node root) {//方法二 队列 O(n) O(n) + List> ans = new ArrayList<>(); + if(root == null) return ans; + Queue queue = new ArrayDeque<>(); + queue.offer(root); + while (!queue.isEmpty()) { + List level = new ArrayList<>(); + int size = queue.size();//通过size的大小来确定每次处理一层 + for (int i = 0; i < size; i++) { + Node node = queue.poll(); + level.add(node.val); + queue.addAll(node.children); + } + ans.add(level); + } + return ans; + } + + + + public List> levelOrder(Node root) {//方法一 递归 另外一种版本(避免全局变量) + return dfs(root, new ArrayList<>(), 0); + } + private List> dfs(Node node, List> res, int level) { + if (node == null) return res; + if (res.size() == level) res.add(new ArrayList<>()); + res.get(level).add(node.val); + for (Node child : node.children) dfs(child, res, level + 1); + return res; + } + + List> res = new ArrayList<>(); + public List> levelOrder_1(Node root) {//方法一 递归法 时间O(n) 空间O(logn)最坏时O(n) + if(root != null) helper(root, 0); + return res; + } + public void helper(Node root, int level) {//递归的辅助函数 + if (res.size() == level) + res.add(new ArrayList<>());//初始时,res为空,每添加一个list,size大小加一,正好代表第几层 + res.get(level).add(root.val); + for (Node node : root.children) + helper(node, level + 1); + } +} \ No newline at end of file diff --git "a/Week_02/\345\220\204\347\247\215\345\240\206\347\232\204\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246.PNG" "b/Week_02/\345\220\204\347\247\215\345\240\206\347\232\204\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246.PNG" new file mode 100644 index 0000000000000000000000000000000000000000..abf0bf99ed1a55e46f44ef105142d774433cbe46 GIT binary patch literal 53431 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 literal 0 HcmV?d00001 diff --git "a/Week_02/\346\211\213\345\212\250\345\256\236\347\216\260\344\272\214\345\217\211\345\240\206MyBinaryHeap.java" "b/Week_02/\346\211\213\345\212\250\345\256\236\347\216\260\344\272\214\345\217\211\345\240\206MyBinaryHeap.java" new file mode 100644 index 00000000..c4a15761 --- /dev/null +++ "b/Week_02/\346\211\213\345\212\250\345\256\236\347\216\260\344\272\214\345\217\211\345\240\206MyBinaryHeap.java" @@ -0,0 +1,103 @@ +import java.sql.SQLOutput; +import java.util.Arrays; +import java.util.NoSuchElementException; + +public class MyBinaryHeap { + private static final int d = 2;//代表分叉个数 + private int[] heap; + private int size; + public MyBinaryHeap(int capacity) { + size = 0; + heap = new int[capacity + 1]; + Arrays.fill(heap, -1); + } + public boolean isEmpty() {//判断是否为空 + return size == 0; + } + public boolean isFull() { + return size == heap.length; + } + + private int parent(int i) {//找父母节点 + return (i - 1) / d; + } + private int child(int i, int k) {//找孩子节点 + return i * d + k; + } + + public void insert(int x) {//先插入到末尾,再进行堆排序 + if (isFull()) { + throw new NoSuchElementException("Heap is full,no space to insert new element."); + } + heap[size] = x; + size++; + heapifyUp(size - 1); + } + private void heapifyUp(int i) { + int inserValue = heap[i]; + while (i > 0 && heap[i] > heap[parent(i)]) { + heap[i] = heap[parent(i)]; + i = parent(i); + } + heap[i] = inserValue; + } + + public int delete(int x) { + if (isEmpty()) { + throw new NoSuchElementException("Heap is empty,no element to delete"); + } + int maxElement = heap[x]; + heap[x] = heap[size - 1]; + size--; + heapifyDown(x); + return maxElement; + } + private void heapifyDown(int i) { + int child_index; + int temp = heap[i];//临时保存要修改的值 + while (child(i, 1) < size) {//确保孩子的下标不会超过size + child_index = maxChild(i); + if (temp > heap[child_index]) + break; + heap[i] = heap[child_index]; + i = child_index; + } + heap[i] = temp; + } + private int maxChild(int i) { + int leftChild = child(i,1); + int rightChild = child(i, 2); + return heap[leftChild] > heap[rightChild] ? leftChild : rightChild; + } + + public void printHeap() { + System.out.print("nHeap = "); + for (int i = 0; i < size; i++) + System.out.print(heap[i] + " "); + System.out.println(); + } + + public int findMax() { + if (isEmpty()) + throw new NoSuchElementException("Heap is empty."); + return heap[0]; + } + + public static void main(String[] args) { + MyBinaryHeap maxHeap = new MyBinaryHeap(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(); + } +} From 2eb8551519339cbeec9316c47110b0862c2fa933 Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Wed, 14 Oct 2020 20:30:36 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8F=90=E4=BA=A4=20?= =?UTF-8?q?=E6=80=BB=E7=BB=93=E6=B7=BB=E5=8A=A0=E4=BA=86MarkDown?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Week_02/README.md | 58 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/Week_02/README.md b/Week_02/README.md index fceb7388..14ffd58f 100644 --- a/Week_02/README.md +++ b/Week_02/README.md @@ -1,27 +1,49 @@ 2020/10/11 学习笔记 -哈希的概念 - hash算法的概念 Hash: 一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 +#哈希的概念 + *hash算法的概念 Hash: 一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 + +#树的一些相关概念 + *链表是特殊的树,树是特殊的图(无环) + *前序:根-左-右 + *中序:左-根-右 + *后序:左-右-根 + *二叉搜索树-中序遍历:升序排列 +#树的面试题解法一般都是递归,为什么? + 1. 该问题可以被分解成若干个重复的子问题; + 2. 该问题与它分解出的子问题可以使用相同的算法来解决; + 3. 有明确的终止条件 树这种数据结构的特点和上述三个特点高度一致,一棵树的每个非叶子节点的子节点也都是一棵树,都是树自然可以使用相同的算法来处理,因为没有环所以天然具有终止条件。 + 4. 另外一方面,树本身是一种非线性的数据结构,循环遍历不易。当然循环遍历也是可以做,树是一种特殊的图,我们完全可以使用图的广度优先遍历算法一层一层的循环遍历整棵树。 + *综上,我们一般还是选择递归的方式来解决树的问题。 +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#学习到的一些新的函数方法或者关键字 + + instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:boolean result = obj instanceof Class -学习到的一些函数新方法 Arrays.sort(char[] ch);//将ch字符数组按照字母顺序排序 + Arrays.equals(char[] ch1, char[] ch2);//比较两个字符数组是否相等 + Integer.MAX_VALUE代表int的最大值,当常数使用 + Integer.MIN_VALUE代表int的最小值 + Integer类型对象 比较值用"equals", 比较 引用 用"==" + System.arraycopy(nums1, 0, nums_copy, 0, m);//nums1从0开始拷贝到nums_copy从0开始长度为m -树的一些相关概念 - 链表是特殊的树,树是特殊的图(无环) - 前序:根-左-右 - 中序:左-根-右 - 后序:左-右-根 - 二叉搜索树-中序遍历:升序排列 -树的面试题解法一般都是递归,为什么? - 1.该问题可以被分解成若干个重复的子问题; - 2.该问题与它分解出的子问题可以使用相同的算法来解决; - 3.有明确的终止条件 树这种数据结构的特点和上述三个特点高度一致,一棵树的每个非叶子节点的子节点也都是一棵树,都是树自然可以使用相同的算法来处理,因为没有环所以天然具有终止条件。 - 4.另外一方面,树本身是一种非线性的数据结构,循环遍历不易。当然循环遍历也是可以做,树是一种特殊的图,我们完全可以使用图的广度优先遍历算法一层一层的循环遍历整棵树。 - 综上,我们一般还是选择递归的方式来解决树的问题。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -学习到的一些新的函数方法或者关键字 - instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:boolean result = obj instanceof Class \ No newline at end of file + + 构建最小堆 + PriorityQueue pq = new PriorityQueue(new Comparator());//默认最小堆 + + 构建最大堆 + PriorityQueue pq = new PriorityQueue(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b - a; + } + }); + + HashMap getOrDeFault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。 + 语法为 hashmap.getOrDeFault(Object key, V defaultValue); + + \ No newline at end of file From 9d6affc72e9ca95ffc76aeecbe618662f70cc5de Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Wed, 14 Oct 2020 20:36:25 +0800 Subject: [PATCH 09/12] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8F=90=E4=BA=A44.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Week_02/README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Week_02/README.md b/Week_02/README.md index 14ffd58f..9cfe0bff 100644 --- a/Week_02/README.md +++ b/Week_02/README.md @@ -1,22 +1,25 @@ -2020/10/11 学习笔记 +#2020/10/11 学习笔记 + +##哈希的概念 -#哈希的概念 *hash算法的概念 Hash: 一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 -#树的一些相关概念 +##树的一些相关概念 + *链表是特殊的树,树是特殊的图(无环) *前序:根-左-右 *中序:左-根-右 *后序:左-右-根 *二叉搜索树-中序遍历:升序排列 -#树的面试题解法一般都是递归,为什么? +##树的面试题解法一般都是递归,为什么? + 1. 该问题可以被分解成若干个重复的子问题; 2. 该问题与它分解出的子问题可以使用相同的算法来解决; 3. 有明确的终止条件 树这种数据结构的特点和上述三个特点高度一致,一棵树的每个非叶子节点的子节点也都是一棵树,都是树自然可以使用相同的算法来处理,因为没有环所以天然具有终止条件。 4. 另外一方面,树本身是一种非线性的数据结构,循环遍历不易。当然循环遍历也是可以做,树是一种特殊的图,我们完全可以使用图的广度优先遍历算法一层一层的循环遍历整棵树。 *综上,我们一般还是选择递归的方式来解决树的问题。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -#学习到的一些新的函数方法或者关键字 +-------------------------------------------------------------------------------------------------------------------------------------------- +##学习到的一些新的函数方法或者关键字 instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:boolean result = obj instanceof Class From 041290c55974d631c83dcbaa8d9513c6d9f7f962 Mon Sep 17 00:00:00 2001 From: zbmgithub <40859700+zbmgithub@users.noreply.github.com> Date: Wed, 14 Oct 2020 20:41:25 +0800 Subject: [PATCH 10/12] Update README.md --- Week_02/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Week_02/README.md b/Week_02/README.md index 9cfe0bff..5fdae7c9 100644 --- a/Week_02/README.md +++ b/Week_02/README.md @@ -1,17 +1,17 @@ -#2020/10/11 学习笔记 +2020/10/11 学习笔记 -##哈希的概念 +哈希的概念 *hash算法的概念 Hash: 一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 -##树的一些相关概念 +树的一些相关概念 *链表是特殊的树,树是特殊的图(无环) *前序:根-左-右 *中序:左-根-右 *后序:左-右-根 *二叉搜索树-中序遍历:升序排列 -##树的面试题解法一般都是递归,为什么? +树的面试题解法一般都是递归,为什么? 1. 该问题可以被分解成若干个重复的子问题; 2. 该问题与它分解出的子问题可以使用相同的算法来解决; @@ -19,7 +19,7 @@ 4. 另外一方面,树本身是一种非线性的数据结构,循环遍历不易。当然循环遍历也是可以做,树是一种特殊的图,我们完全可以使用图的广度优先遍历算法一层一层的循环遍历整棵树。 *综上,我们一般还是选择递归的方式来解决树的问题。 -------------------------------------------------------------------------------------------------------------------------------------------- -##学习到的一些新的函数方法或者关键字 +学习到的一些新的函数方法或者关键字 instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:boolean result = obj instanceof Class @@ -36,7 +36,7 @@ System.arraycopy(nums1, 0, nums_copy, 0, m);//nums1从0开始拷贝到nums_copy从0开始长度为m 构建最小堆 - PriorityQueue pq = new PriorityQueue(new Comparator());//默认最小堆 + PriorityQueue pq = new PriorityQueue();//默认最小堆 构建最大堆 PriorityQueue pq = new PriorityQueue(new Comparator() { @@ -49,4 +49,4 @@ HashMap getOrDeFault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。 语法为 hashmap.getOrDeFault(Object key, V defaultValue); - \ No newline at end of file + From 95fc95fa6f5e300798209d38a40c618d71911b0f Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Thu, 15 Oct 2020 15:18:55 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8F=90=E4=BA=A41.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Week_03/README.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/Week_03/README.md b/Week_03/README.md index 50de3041..a3601a99 100644 --- a/Week_03/README.md +++ b/Week_03/README.md @@ -1 +1,31 @@ -学习笔记 \ No newline at end of file +2020/10/15 学习笔记 + +递归 + + 四个结构模块 + 1.终止条件 + 2.处理当前逻辑 + 3.下探到下一层 + 4.清理当前层 + + 思维要点 + 1.不要人肉递归 + 2.找到最近重复子问题 + 3.数学归纳法思维 + + 代码模板 +// 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 + +} + From f045e4faeb3717020b0838a7a28310c71071fea9 Mon Sep 17 00:00:00 2001 From: Z_B_M Date: Thu, 15 Oct 2020 15:28:05 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Week_03/README.md | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/Week_03/README.md b/Week_03/README.md index a3601a99..6092bb44 100644 --- a/Week_03/README.md +++ b/Week_03/README.md @@ -13,19 +13,20 @@ 2.找到最近重复子问题 3.数学归纳法思维 - 代码模板 -// 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 - -} +代码模板 + + // 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 + + }