Skip to content

Commit bed2093

Browse files
复习
1 parent 24c4f61 commit bed2093

7 files changed

Lines changed: 69 additions & 115 deletions

File tree

26.9 KB
Binary file not shown.

JAVA/2.1 自定义 Java 注解处理器.md

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,6 @@
22
33
[toc]
44

5-
本文介绍了如何自定义 Java 注解处理器及涉及到的相关知识,看完本文可以很轻松看懂并理解各大开源框架的注解处理器的应用。
6-
7-
> 《游园不值》
8-
> 应怜屐齿印苍苔 ,小扣柴扉久不开 。
9-
> 春色满园关不住 ,一枝红杏出墙来 。
10-
>
11-
> - 宋,叶绍翁
12-
13-
关于自定义 Java 注解请查看[自定义注解](https://yuweiguocn.github.io/java-annotation/)
14-
15-
> 本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发。
16-
175
基本实现
186
--------------------
197

3.33 KB
Binary file not shown.

算法/7. 二分查找.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
使用二分查找必须是单调有序的数据结构,一般情况下二分查找造作数据代码简单又高效,但是操作礼物链表这种就有点难了,二分查找具有 O(logn) 的时间复杂度,一般作为体验出现。
1+
使用二分查找**必须是单调有序的数据结构**,一般情况下二分查找造作数据代码简单又高效,但是操作礼物链表这种就有点难了,二分查找具有 O(logn) 的时间复杂度,一般作为体验出现。
22

33
代码模板
44

算法/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
# 应对面试
2+
3+
核心理念:不用学原理,刷题就行。客户端考察的算法不会太难的。
4+
5+
刷题资料:
6+
7+
1. [剑指 offer 所有](https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/50ywkd/)
8+
2. [LeetCode 精选 TOP 面试题](https://leetcode-cn.com/problem-list/2ckc81c/)
9+
10+
1. [LeetCode 热题 HOT 100](https://leetcode-cn.com/problem-list/2cktkvj/)
11+
2. [牛客客户端热门题目](https://www.nowcoder.com/exam/oj?tab=算法篇&topicId=117&page=2)
12+
13+
1. [codetop 客户端常考](https://codetop.cc/home)
14+
15+
反复刷前三条里面的所有题目,四五条用于查缺补漏,正式面试的时候使用四五条作为专项练习
16+
17+
18+
19+
20+
21+
# 以下内容适合研究不适合应对面试
22+
123
主要按照极客时间算法与数据结构之美学习,每一个算法都单独写一个笔记,再附上LeetCode上对应的联系提解题思路,解题思路要附加上演变过程。
224

325

算法/剑指 offer.md

Lines changed: 45 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -418,103 +418,6 @@ class Solution {
418418
}
419419
```
420420

421-
# 分治算法
422-
423-
## [07、重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/)
424-
425-
重建二叉树的关键在于中序遍历的结果:[左子树区间]root[右子树区间],通过中序遍历的结果可以清晰的得出根节点与左右子树之间的关系。
426-
427-
此题要求使用中序遍历与前序遍历的结果还原二叉树,从中我们可得到如下信息:
428-
429-
1. 中序遍历的特点:[左子树区间]root[右子树区间]
430-
431-
2. 前序遍历的特点:root [左子树区间][右子树区间]
432-
433-
由于题目说明不存在重复的值,所以我们可以将中序遍历的结果与位置索引建立一个 map,通过前序遍历中的头结点即可在时间复杂度为 O(1) 的情况下从 map 中获取左右区间的边界。
434-
435-
在 map 之外我们还需要双指针来分别标记位于中序遍历中的左右子树边界;还需要一个全局变量指明当前 root 位于前序遍历的索引;根据这些值通过递归不断的压缩左右区间,最终重建二叉树。
436-
437-
```java
438-
class Solution {
439-
private Map<Integer, Integer> mCache = new HashMap<>();
440-
private int mCurRootIndexOnPreorder = 0;
441-
public TreeNode buildTree(int[] preorder, int[] inorder) {
442-
// 中序遍历是关系,需要将值和位置的关系存储起来
443-
for (int i = 0; i < inorder.length; i++) {
444-
mCache.put(inorder[i], i);
445-
}
446-
447-
return buildTree(preorder, inorder, 0, inorder.length - 1);
448-
}
449-
450-
private TreeNode buildTree(int[] preorder, int[] inorder, int start, int end) {
451-
// 边界条件
452-
if (start > end) {
453-
return null;
454-
}
455-
// 获取头结点的值
456-
int rootVal = preorder[mCurRootIndexOnPreorder++];
457-
// 获取头结点在中序遍历的位置
458-
int rootIndexOfInoder = mCache.get(rootVal);
459-
TreeNode root = new TreeNode(rootVal);
460-
// 递归建立左右子树
461-
root.left = buildTree(preorder, inorder, start, rootIndexOfInoder - 1);
462-
root.right = buildTree(preorder, inorder, rootIndexOfInoder + 1, end);
463-
return root;
464-
}
465-
}
466-
467-
```
468-
469-
470-
471-
472-
473-
## [33、二叉搜索树的后序遍历序列](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/)
474-
475-
这道题使用单调栈可以获得最优解,而且能更好的理解。
476-
477-
首先明确什么是二叉搜索树:左节点 <根节点 < 右节点(left < root < right)即越往右数值越大,但是此题给出的是后续遍: left -> right -> root 并不满足单调性。但是我们将顺序反过来就形成了 root -> right -> left 即可以得到一个从小 -> 大 -> 小的两个严格单调区间。此时我们就可以使用单调栈来判断题目中提出的数组是否满足二叉搜索树的递增关系了。
478-
479-
一开始我们将反序后的数组逐个入栈,如果不满足单调递增性,这说明进入了 [left 左子树区间]。此时要做的是找到当前值(左子树值)所对应的根节点。怎么做呢?拿栈顶元素与当前值进行比较,直到把比当前值大的数全部出栈为止,最后一个出栈的就是当前值对应的根节点。
480-
481-
这里要注意的是 root > left 这个关系,如果当前值小于了 [left 左子树区间] 的值,则返回 false。
482-
483-
484-
485-
就这样一路比下去,如果所有的左子树值都小于所对应的 root 则满足二叉搜索树特点,否则就不是。
486-
487-
```java
488-
class Solution {
489-
public boolean verifyPostorder(int[] postorder) {
490-
// 判定边界条件
491-
if (postorder == null || postorder.length == 0) {
492-
return true;
493-
}
494-
final Stack<Integer> stack = new Stack<>();
495-
// 简化判断左子树与 root 关系的判定逻辑
496-
int root = Integer.MAX_VALUE;
497-
// 将数组反过来得到单调关系
498-
for (int i = postorder.length - 1; i >= 0; i--) {
499-
// 左子树大于了 root, 不满足二叉搜索树特性
500-
if (postorder[i] > root) {
501-
return false;
502-
}
503-
// 不满足单调性,说明进入了左子树区间,开始寻找当前左子树对应的 root
504-
while (!stack.isEmpty() && postorder[i] < stack.peek()) {
505-
root = stack.pop();
506-
}
507-
stack.push(postorder[i]);
508-
}
509-
return true;
510-
}
511-
}
512-
```
513-
514-
# [17、打印从 1 到最大的 n 位数](https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/)
515-
516-
517-
518421
# 分治算法
519422

520423
## [07. 重建二叉树](https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/99lxci/)
@@ -633,7 +536,7 @@ class Solution {
633536

634537

635538

636-
## 解法1:递推,时间复杂度 O(logn)、空间复杂度O(1)
539+
### 解法1:递推,时间复杂度 O(logn)、空间复杂度O(1)
637540

638541
```java
639542
class Solution {
@@ -675,7 +578,7 @@ class Solution {
675578
}
676579
```
677580

678-
## 解法2: 递归,时间复杂度 O(logn)、空间复杂度O(n)
581+
### 解法2: 递归,时间复杂度 O(logn)、空间复杂度O(n)
679582

680583
```java
681584
class Solution {
@@ -846,3 +749,46 @@ class Solution {
846749
}
847750
```
848751

752+
## [33、二叉搜索树的后序遍历序列](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/)
753+
754+
这道题使用单调栈可以获得最优解,而且能更好的理解。
755+
756+
首先明确什么是二叉搜索树:左节点 <根节点 < 右节点(left < root < right)即越往右数值越大,但是此题给出的是后续遍: left -> right -> root 并不满足单调性。但是我们将顺序反过来就形成了 root -> right -> left 即可以得到一个从小 -> 大 -> 小的两个严格单调区间。此时我们就可以使用单调栈来判断题目中提出的数组是否满足二叉搜索树的递增关系了。
757+
758+
一开始我们将反序后的数组逐个入栈,如果不满足单调递增性,这说明进入了 [left 左子树区间]。此时要做的是找到当前值(左子树值)所对应的根节点。怎么做呢?拿栈顶元素与当前值进行比较,直到把比当前值大的数全部出栈为止,最后一个出栈的就是当前值对应的根节点。
759+
760+
这里要注意的是 root > left 这个关系,如果当前值小于了 [left 左子树区间] 的值,则返回 false。
761+
762+
763+
764+
就这样一路比下去,如果所有的左子树值都小于所对应的 root 则满足二叉搜索树特点,否则就不是。
765+
766+
```java
767+
class Solution {
768+
public boolean verifyPostorder(int[] postorder) {
769+
// 判定边界条件
770+
if (postorder == null || postorder.length == 0) {
771+
return true;
772+
}
773+
final Stack<Integer> stack = new Stack<>();
774+
// 简化判断左子树与 root 关系的判定逻辑
775+
int root = Integer.MAX_VALUE;
776+
// 将数组反过来得到单调关系
777+
for (int i = postorder.length - 1; i >= 0; i--) {
778+
// 左子树大于了 root, 不满足二叉搜索树特性
779+
if (postorder[i] > root) {
780+
return false;
781+
}
782+
// 不满足单调性,说明进入了左子树区间,开始寻找当前左子树对应的 root
783+
while (!stack.isEmpty() && postorder[i] < stack.peek()) {
784+
root = stack.pop();
785+
}
786+
stack.push(postorder[i]);
787+
}
788+
return true;
789+
}
790+
}
791+
```
792+
793+
## [17、打印从 1 到最大的 n 位数](https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/)
794+

算法/排序算法.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
33
[toc]
44

5-
6-
75
# 十种常见排序算法可以分为两大类:
86

97
1. 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破 O(nlogn),因此也称为非线性时间比较类排序。
@@ -574,7 +572,7 @@ class Solution {
574572

575573

576574
**4. 算法分析**
577-
快速排序的核心是能准确有效的找到数组的基准数索引,我们以数组 27,44,38,5,47,15,36,26,3,2,46,4,19,50,48 为例来演寻找 pivot 的过程
575+
快速排序的**核心是能准确有效的找到数组的基准数索引**,我们以数组 27,44,38,5,47,15,36,26,3,2,46,4,19,50,48 为例来演寻找 pivot 的过程
578576
![](images/20200623155645647.png)
579577

580578
* **第一次 while 循环**

0 commit comments

Comments
 (0)