auto commit

This commit is contained in:
CyC2018
2019-11-02 17:33:10 +08:00
parent 906d2ff2f9
commit 23d7c89fbe
319 changed files with 803 additions and 803 deletions

View File

@ -8,13 +8,13 @@
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?f(n)=\left\{\begin{array}{rcl}0&&{n=0}\\1&&{n=1}\\f(n-1)+f(n-2)&&{n>1}\end{array}\right." class="mathjax-pic"/></div> <br> -->
<div align="center"> <img src="pics/45be9587-6069-4ab7-b9ac-840db1a53744.jpg" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/45be9587-6069-4ab7-b9ac-840db1a53744.jpg" width="300px"> </div><br>
## 解题思路
如果使用递归求解会重复计算一些子问题例如计算 f(4) 需要计算 f(3) f(2)计算 f(3) 需要计算 f(2) f(1)可以看到 f(2) 被重复计算了
<div align="center"> <img src="pics/c13e2a3d-b01c-4a08-a69b-db2c4e821e09.png" width="350px"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c13e2a3d-b01c-4a08-a69b-db2c4e821e09.png" width="350px"/> </div><br>
递归是将一个问题划分成多个子问题求解动态规划也是如此但是动态规划会把子问题的解缓存起来从而避免重复求解子问题
@ -71,4 +71,4 @@ public class Solution {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,23 +6,23 @@
我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形请问用 n 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形总共有多少种方法
<div align="center"> <img src="pics/b903fda8-07d0-46a7-91a7-e803892895cf.gif" width="100px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b903fda8-07d0-46a7-91a7-e803892895cf.gif" width="100px"> </div><br>
## 解题思路
n 1 只有一种覆盖方法
<div align="center"> <img src="pics/f6e146f1-57ad-411b-beb3-770a142164ef.png" width="100px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f6e146f1-57ad-411b-beb3-770a142164ef.png" width="100px"> </div><br>
n 2 有两种覆盖方法
<div align="center"> <img src="pics/fb3b8f7a-4293-4a38-aae1-62284db979a3.png" width="200px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/fb3b8f7a-4293-4a38-aae1-62284db979a3.png" width="200px"> </div><br>
要覆盖 2\*n 的大矩形可以先覆盖 2\*1 的矩形再覆盖 2\*(n-1) 的矩形或者先覆盖 2\*2 的矩形再覆盖 2\*(n-2) 的矩形而覆盖 2\*(n-1) 2\*(n-2) 的矩形可以看成子问题该问题的递推公式如下
<!-- <div align="center"><img src="https://latex.codecogs.com/gif.latex?f(n)=\left\{\begin{array}{rcl}1&&{n=1}\\2&&{n=2}\\f(n-1)+f(n-2)&&{n>1}\end{array}\right." class="mathjax-pic"/></div> <br> -->
<div align="center"> <img src="pics/508c6e52-9f93-44ed-b6b9-e69050e14807.jpg" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/508c6e52-9f93-44ed-b6b9-e69050e14807.jpg" width="350px"> </div><br>
```java
public int RectCover(int n) {
@ -44,4 +44,4 @@ public int RectCover(int n) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,21 +6,21 @@
一只青蛙一次可以跳上 1 级台阶也可以跳上 2 求该青蛙跳上一个 n 级的台阶总共有多少种跳法
<div align="center"> <img src="pics/9dae7475-934f-42e5-b3b3-12724337170a.png" width="380px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9dae7475-934f-42e5-b3b3-12724337170a.png" width="380px"> </div><br>
## 解题思路
n = 1 只有一种跳法
<div align="center"> <img src="pics/72aac98a-d5df-4bfa-a71a-4bb16a87474c.png" width="250px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/72aac98a-d5df-4bfa-a71a-4bb16a87474c.png" width="250px"> </div><br>
n = 2 有两种跳法
<div align="center"> <img src="pics/1b80288d-1b35-4cd3-aa17-7e27ab9a2389.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1b80288d-1b35-4cd3-aa17-7e27ab9a2389.png" width="300px"> </div><br>
n 阶台阶可以先跳 1 阶台阶再跳 n-1 阶台阶或者先跳 2 阶台阶再跳 n-2 阶台阶 n-1 n-2 阶台阶的跳法可以看成子问题该问题的递推公式为
<div align="center"> <img src="pics/508c6e52-9f93-44ed-b6b9-e69050e14807.jpg" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/508c6e52-9f93-44ed-b6b9-e69050e14807.jpg" width="350px"> </div><br>
```java
public int JumpFloor(int n) {
@ -42,4 +42,4 @@ public int JumpFloor(int n) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
一只青蛙一次可以跳上 1 级台阶也可以跳上 2 ... 它也可以跳上 n 求该青蛙跳上一个 n 级的台阶总共有多少种跳法
<div align="center"> <img src="pics/cd411a94-3786-4c94-9e08-f28320e010d5.png" width="380px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/cd411a94-3786-4c94-9e08-f28320e010d5.png" width="380px"> </div><br>
## 解题思路
@ -62,4 +62,4 @@ public int JumpFloorII(int target) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,13 +6,13 @@
把一个数组最开始的若干个元素搬到数组的末尾我们称之为数组的旋转输入一个非递减排序的数组的一个旋转输出旋转数组的最小元素
<div align="center"> <img src="pics/0038204c-4b8a-42a5-921d-080f6674f989.png" width="210px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/0038204c-4b8a-42a5-921d-080f6674f989.png" width="210px"> </div><br>
## 解题思路
将旋转数组对半分可以得到一个包含最小元素的新旋转数组以及一个非递减排序的数组新的旋转数组的数组元素是原数组的一半从而将问题规模减少了一半这种折半性质的算法的时间复杂度为 O(logN)为了方便这里将 log<sub>2</sub>N 写为 logN
<div align="center"> <img src="pics/424f34ab-a9fd-49a6-9969-d76b42251365.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/424f34ab-a9fd-49a6-9969-d76b42251365.png" width="300px"> </div><br>
此时问题的关键在于确定对半分得到的两个数组哪一个是旋转数组哪一个是非递减数组我们很容易知道非递减数组的第一个元素一定小于等于最后一个元素
@ -69,4 +69,4 @@ private int minNumber(int[] nums, int l, int h) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -8,13 +8,13 @@
例如下面的矩阵包含了一条 bfce 路径
<div align="center"> <img src="pics/1db1c7ea-0443-478b-8df9-7e33b1336cc4.png" width="200px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1db1c7ea-0443-478b-8df9-7e33b1336cc4.png" width="200px"> </div><br>
## 解题思路
使用回溯法backtracking进行求解它是一种暴力搜索方法通过搜索所有可能的结果来求解问题回溯法在一次搜索结束时需要进行回溯回退将这一次搜索过程中设置的状态进行清除从而开始一次新的搜索过程例如下图示例中 f 开始下一步有 4 种搜索可能如果先搜索 b需要将 b 标记为已经使用防止重复使用在这一次搜索结束之后需要将 b 的已经使用状态清除并搜索 c
<div align="center"> <img src="pics/dc964b86-7a08-4bde-a3d9-e6ddceb29f98.png" width="200px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/dc964b86-7a08-4bde-a3d9-e6ddceb29f98.png" width="200px"> </div><br>
本题的输入是数组而不是矩阵二维数组因此需要先将数组转换成矩阵
@ -68,4 +68,4 @@ private char[][] buildMatrix(char[] array) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -62,4 +62,4 @@ private void initDigitSum() {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -56,4 +56,4 @@ public int integerBreak(int n) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -44,4 +44,4 @@ public int NumberOf1(int n) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -12,7 +12,7 @@
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?x^n=\left\{\begin{array}{rcl}(x*x)^{n/2}&&{n\%2=0}\\x*(x*x)^{n/2}&&{n\%2=1}\end{array}\right." class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/48b1d459-8832-4e92-938a-728aae730739.jpg" width="330px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/48b1d459-8832-4e92-938a-728aae730739.jpg" width="330px"> </div><br>
因为 (x\*x)<sup>n/2</sup> 可以通过递归求解并且每次递归 n 都减小一半因此整个算法的时间复杂度为 O(logN)
@ -40,4 +40,4 @@ public double Power(double base, int exponent) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -44,4 +44,4 @@ private void printNumber(char[] number) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -4,11 +4,11 @@
如果该节点不是尾节点那么可以直接将下一个节点的值赋给该节点然后令该节点指向下下个节点再删除下一个节点时间复杂度为 O(1)
<div align="center"> <img src="pics/1176f9e1-3442-4808-a47a-76fbaea1b806.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1176f9e1-3442-4808-a47a-76fbaea1b806.png" width="600"/> </div><br>
否则就需要先遍历链表找到节点的前一个节点然后让前一个节点指向 null时间复杂度为 O(N)
<div align="center"> <img src="pics/4bf8d0ba-36f0-459e-83a0-f15278a5a157.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/4bf8d0ba-36f0-459e-83a0-f15278a5a157.png" width="600"/> </div><br>
综上如果进行 N 次操作那么大约需要操作节点的次数为 N-1+N=2N-1其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数(2N-1)/N \~ 2因此该算法的平均时间复杂度为 O(1)
@ -41,4 +41,4 @@ public ListNode deleteNode(ListNode head, ListNode tobeDelete) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -4,7 +4,7 @@
## 题目描述
<div align="center"> <img src="pics/17e301df-52e8-4886-b593-841a16d13e44.png" width="450"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/17e301df-52e8-4886-b593-841a16d13e44.png" width="450"/> </div><br>
## 解题描述
@ -29,4 +29,4 @@ public ListNode deleteDuplication(ListNode pHead) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -44,4 +44,4 @@ public boolean match(char[] str, char[] pattern) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -53,4 +53,4 @@ public boolean isNumeric(char[] str) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
需要保证奇数和奇数偶数和偶数之间的相对位置不变这和书本不太一样
<div align="center"> <img src="pics/d03a2efa-ef19-4c96-97e8-ff61df8061d3.png" width="200px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/d03a2efa-ef19-4c96-97e8-ff61df8061d3.png" width="200px"> </div><br>
## 解题思路
@ -64,4 +64,4 @@ private void swap(int[] nums, int i, int j) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
设链表的长度为 N设置两个指针 P1 P2先让 P1 移动 K 个节点则还有 N - K 个节点可以移动此时让 P1 P2 同时移动可以知道当 P1 移动到链表结尾时P2 移动到第 N - K 个节点处该位置就是倒数第 K 个节点
<div align="center"> <img src="pics/6b504f1f-bf76-4aab-a146-a9c7a58c2029.png" width="500"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/6b504f1f-bf76-4aab-a146-a9c7a58c2029.png" width="500"/> </div><br>
```java
public ListNode FindKthToTail(ListNode head, int k) {
@ -31,4 +31,4 @@ public ListNode FindKthToTail(ListNode head, int k) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -12,7 +12,7 @@
在相遇点slow 要到环的入口点还需要移动 z 个节点如果让 fast 重新从头开始移动并且速度变为每次移动一个节点那么它到环入口点还需要移动 x 个节点在上面已经推导出 x=z因此 fast slow 将在环入口点相遇
<div align="center"> <img src="pics/bb7fc182-98c2-4860-8ea3-630e27a5f29f.png" width="500"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/bb7fc182-98c2-4860-8ea3-630e27a5f29f.png" width="500"/> </div><br>
```java
public ListNode EntryNodeOfLoop(ListNode pHead) {
@ -37,4 +37,4 @@ public ListNode EntryNodeOfLoop(ListNode pHead) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -40,4 +40,4 @@ public ListNode ReverseList(ListNode head) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -4,7 +4,7 @@
## 题目描述
<div align="center"> <img src="pics/c094d2bc-ec75-444b-af77-d369dfb6b3b4.png" width="400"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c094d2bc-ec75-444b-af77-d369dfb6b3b4.png" width="400"/> </div><br>
## 解题思路
@ -55,4 +55,4 @@ public ListNode Merge(ListNode list1, ListNode list2) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -4,7 +4,7 @@
## 题目描述
<div align="center"> <img src="pics/84a5b15a-86c5-4d8e-9439-d9fd5a4699a1.jpg" width="450"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/84a5b15a-86c5-4d8e-9439-d9fd5a4699a1.jpg" width="450"/> </div><br>
## 解题思路
@ -31,4 +31,4 @@ private boolean isSubtreeWithRoot(TreeNode root1, TreeNode root2) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -4,7 +4,7 @@
## 题目描述
<div align="center"> <img src="pics/0c12221f-729e-4c22-b0ba-0dfc909f8adf.jpg" width="300"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/0c12221f-729e-4c22-b0ba-0dfc909f8adf.jpg" width="300"/> </div><br>
## 解题思路
@ -29,4 +29,4 @@ private void swap(TreeNode root) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -4,7 +4,7 @@
## 题目描述
<div align="center"> <img src="pics/0c12221f-729e-4c22-b0ba-0dfc909f8adf.jpg" width="300"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/0c12221f-729e-4c22-b0ba-0dfc909f8adf.jpg" width="300"/> </div><br>
## 解题思路
@ -31,4 +31,4 @@ boolean isSymmetrical(TreeNode t1, TreeNode t2) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
下图的矩阵顺时针打印结果为1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10
<div align="center"> <img src="pics/48517227-324c-4664-bd26-a2d2cffe2bfe.png" width="200px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/48517227-324c-4664-bd26-a2d2cffe2bfe.png" width="200px"> </div><br>
## 解题思路
@ -36,4 +36,4 @@ public ArrayList<Integer> printMatrix(int[][] matrix) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -24,7 +24,7 @@ Output:
(2, 3, 1, 0, 2, 5) 为例遍历到位置 4 该位置上的数为 2但是第 2 个位置上已经有一个 2 的值了因此可以知道 2 重复
<div align="center"> <img src="pics/643b6f18-f933-4ac5-aa7a-e304dbd7fe49.gif" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/643b6f18-f933-4ac5-aa7a-e304dbd7fe49.gif" width="350px"> </div><br>
```java
@ -55,4 +55,4 @@ private void swap(int[] nums, int i, int j) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -36,4 +36,4 @@ public int min() {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -33,4 +33,4 @@ public boolean IsPopOrder(int[] pushSequence, int[] popSequence) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -8,7 +8,7 @@
例如以下二叉树层次遍历的结果为1,2,3,4,5,6,7
<div align="center"> <img src="pics/d5e838cf-d8a2-49af-90df-1b2a714ee676.jpg" width="250"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/d5e838cf-d8a2-49af-90df-1b2a714ee676.jpg" width="250"/> </div><br>
## 解题思路
@ -41,4 +41,4 @@ public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -36,4 +36,4 @@ ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -40,4 +40,4 @@ public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -8,7 +8,7 @@
例如下图是后序遍历序列 1,3,2 所对应的二叉搜索树
<div align="center"> <img src="pics/13454fa1-23a8-4578-9663-2b13a6af564a.jpg" width="150"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/13454fa1-23a8-4578-9663-2b13a6af564a.jpg" width="150"/> </div><br>
## 解题思路
@ -38,4 +38,4 @@ private boolean verify(int[] sequence, int first, int last) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -8,7 +8,7 @@
下图的二叉树有两条和为 22 的路径10, 5, 7 10, 12
<div align="center"> <img src="pics/ed77b0e6-38d9-4a34-844f-724f3ffa2c12.jpg" width="200"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ed77b0e6-38d9-4a34-844f-724f3ffa2c12.jpg" width="200"/> </div><br>
## 解题思路
@ -40,4 +40,4 @@ private void backtracking(TreeNode node, int target, ArrayList<Integer> path) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -18,21 +18,21 @@ public class RandomListNode {
}
```
<div align="center"> <img src="pics/66a01953-5303-43b1-8646-0c77b825e980.png" width="300"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/66a01953-5303-43b1-8646-0c77b825e980.png" width="300"/> </div><br>
## 解题思路
第一步在每个节点的后面插入复制的节点
<div align="center"> <img src="pics/dfd5d3f8-673c-486b-8ecf-d2082107b67b.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/dfd5d3f8-673c-486b-8ecf-d2082107b67b.png" width="600"/> </div><br>
第二步对复制节点的 random 链接进行赋值
<div align="center"> <img src="pics/cafbfeb8-7dfe-4c0a-a3c9-750eeb824068.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/cafbfeb8-7dfe-4c0a-a3c9-750eeb824068.png" width="600"/> </div><br>
第三步拆分
<div align="center"> <img src="pics/e151b5df-5390-4365-b66e-b130cd253c12.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e151b5df-5390-4365-b66e-b130cd253c12.png" width="600"/> </div><br>
```java
public RandomListNode Clone(RandomListNode pHead) {
@ -71,4 +71,4 @@ public RandomListNode Clone(RandomListNode pHead) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
输入一棵二叉搜索树将该二叉搜索树转换成一个排序的双向链表要求不能创建任何新的结点只能调整树中结点指针的指向
<div align="center"> <img src="pics/05a08f2e-9914-4a77-92ef-aebeaecf4f66.jpg" width="400"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/05a08f2e-9914-4a77-92ef-aebeaecf4f66.jpg" width="400"/> </div><br>
## 解题思路
@ -38,4 +38,4 @@ private void inOrder(TreeNode node) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -43,4 +43,4 @@ private TreeNode Deserialize() {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -44,4 +44,4 @@ private void backtracking(char[] chars, boolean[] hasUsed, StringBuilder s) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -31,4 +31,4 @@ public int MoreThanHalfNum_Solution(int[] nums) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -28,7 +28,7 @@ Given target = 20, return false.
该二维数组中的一个数小于它的数一定在其左边大于它的数一定在其下边因此从右上角开始查找就可以根据 target 和当前元素的大小关系来缩小查找区间当前元素的查找区间为左下角的所有元素
<div align="center"> <img src="pics/35a8c711-0dc0-4613-95f3-be96c6c6e104.gif" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/35a8c711-0dc0-4613-95f3-be96c6c6e104.gif" width="400px"> </div><br>
```java
public boolean Find(int target, int[][] matrix) {
@ -53,4 +53,4 @@ public boolean Find(int target, int[][] matrix) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -85,4 +85,4 @@ public ArrayList<Integer> GetLeastNumbers_Solution(int[] nums, int k) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -44,4 +44,4 @@ public Double GetMedian() {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -29,4 +29,4 @@ public char FirstAppearingOnce() {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -28,4 +28,4 @@ public int FindGreatestSumOfSubArray(int[] nums) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -22,4 +22,4 @@ public int NumberOf1Between1AndN_Solution(int n) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -58,4 +58,4 @@ private int getDigitAtIndex(int index, int place) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -31,4 +31,4 @@ public String PrintMinNumber(int[] numbers) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -35,4 +35,4 @@ public int numDecodings(String s) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -39,4 +39,4 @@ public int getMost(int[][] values) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -33,4 +33,4 @@ public int longestSubStringWithoutDuplication(String str) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -34,4 +34,4 @@ public int GetUglyNumber_Solution(int N) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -27,7 +27,7 @@ Output:
<div align="center"> <img src="pics/f7c1fea2-c1e7-4d31-94b5-0d9df85e093c.gif" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f7c1fea2-c1e7-4d31-94b5-0d9df85e093c.gif" width="350px"> </div><br>
```java
public String replaceSpace(StringBuffer str) {
@ -56,4 +56,4 @@ public String replaceSpace(StringBuffer str) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -53,4 +53,4 @@ public int FirstNotRepeatingChar2(String str) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -52,4 +52,4 @@ private void merge(int[] nums, int l, int m, int h) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -4,7 +4,7 @@
## 题目描述
<div align="center"> <img src="pics/5f1cb999-cb9a-4f6c-a0af-d90377295ab8.png" width="500"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/5f1cb999-cb9a-4f6c-a0af-d90377295ab8.png" width="500"/> </div><br>
## 解题思路
@ -28,4 +28,4 @@ public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -40,4 +40,4 @@ private int binarySearch(int[] nums, int K) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -31,4 +31,4 @@ private void inOrder(TreeNode root, int k) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
从根结点到叶结点依次经过的结点含根叶结点形成树的一条路径最长路径的长度为树的深度
<div align="center"> <img src="pics/ba355101-4a93-4c71-94fb-1da83639727b.jpg" width="350px"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ba355101-4a93-4c71-94fb-1da83639727b.jpg" width="350px"/> </div><br>
## 解题思路
@ -21,4 +21,4 @@ public int TreeDepth(TreeNode root) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
平衡二叉树左右子树高度差不超过 1
<div align="center"> <img src="pics/af1d1166-63af-47b6-9aa3-2bf2bd37bd03.jpg" width="250px"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/af1d1166-63af-47b6-9aa3-2bf2bd37bd03.jpg" width="250px"/> </div><br>
## 解题思路
@ -34,4 +34,4 @@ private int height(TreeNode root) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -32,4 +32,4 @@ public void FindNumsAppearOnce(int[] nums, int num1[], int num2[]) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -35,4 +35,4 @@ public ArrayList<Integer> FindNumbersWithSum(int[] array, int sum) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -47,4 +47,4 @@ public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -51,4 +51,4 @@ private void swap(char[] c, int i, int j) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -45,4 +45,4 @@ private void swap(char[] chars, int i, int j) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -33,4 +33,4 @@ public ArrayList<Integer> maxInWindows(int[] num, int size) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
从尾到头反过来打印出每个结点的值
<div align="center"> <img src="pics/f5792051-d9b2-4ca4-a234-a4a2de3d5a57.png" width="280px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f5792051-d9b2-4ca4-a234-a4a2de3d5a57.png" width="280px"> </div><br>
## 解题思路
@ -34,7 +34,7 @@ public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
- 头结点是在头插法中使用的一个额外节点这个节点不存储值
- 第一个节点就是链表的第一个真正存储值的节点
<div align="center"> <img src="pics/0dae7e93-cfd1-4bd3-97e8-325b032b716f.gif" width="370px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/0dae7e93-cfd1-4bd3-97e8-325b032b716f.gif" width="370px"> </div><br>
```java
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
@ -61,7 +61,7 @@ public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
栈具有后进先出的特点在遍历链表时将值按顺序放入栈中最后出栈的顺序即为逆序
<div align="center"> <img src="pics/9d1deeba-4ae1-41dc-98f4-47d85b9831bc.gif" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9d1deeba-4ae1-41dc-98f4-47d85b9831bc.gif" width="300px"> </div><br>
```java
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
@ -82,4 +82,4 @@ public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
n 个骰子扔在地上求点数和为 s 的概率
<div align="center"> <img src="pics/195f8693-5ec4-4987-8560-f25e365879dd.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/195f8693-5ec4-4987-8560-f25e365879dd.png" width="300px"> </div><br>
## 解题思路
@ -76,4 +76,4 @@ public List<Map.Entry<Integer, Double>> dicesSum(int n) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
五张牌其中大小鬼为癞子牌面为 0判断这五张牌是否能组成顺子
<div align="center"> <img src="pics/eaa506b6-0747-4bee-81f8-3cda795d8154.png" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/eaa506b6-0747-4bee-81f8-3cda795d8154.png" width="350px"> </div><br>
## 解题思路
@ -41,4 +41,4 @@ public boolean isContinuous(int[] nums) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -25,4 +25,4 @@ public int LastRemaining_Solution(int n, int m) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
可以有一次买入和一次卖出买入必须在前求最大收益
<div align="center"> <img src="pics/42661013-750f-420b-b3c1-437e9a11fb65.png" width="220px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/42661013-750f-420b-b3c1-437e9a11fb65.png" width="220px"> </div><br>
## 解题思路
@ -31,4 +31,4 @@ public int maxProfit(int[] prices) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -27,4 +27,4 @@ public int Sum_Solution(int n) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -23,4 +23,4 @@ public int Add(int a, int b) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -6,7 +6,7 @@
给定一个数组 A[0, 1,..., n-1]请构建一个数组 B[0, 1,..., n-1]其中 B 中的元素 B[i]=A[0]\*A[1]\*...\*A[i-1]\*A[i+1]\*...\*A[n-1]要求不能使用除法
<div align="center"> <img src="pics/4240a69f-4d51-4d16-b797-2dfe110f30bd.png" width="250px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/4240a69f-4d51-4d16-b797-2dfe110f30bd.png" width="250px"> </div><br>
## 解题思路
@ -28,4 +28,4 @@ public int[] multiply(int[] A) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -41,4 +41,4 @@ public int StrToInt(String str) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -8,7 +8,7 @@
二叉查找树中两个节点 p, q 的公共祖先 root 满足 root.val >= p.val && root.val <= q.val
<div align="center"> <img src="pics/047faac4-a368-4565-8331-2b66253080d3.jpg" width="220"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/047faac4-a368-4565-8331-2b66253080d3.jpg" width="220"/> </div><br>
```java
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
@ -28,7 +28,7 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
在左右子树中查找是否存在 p 或者 q如果 p q 分别在两个子树中那么就说明根节点就是最低公共祖先
<div align="center"> <img src="pics/d27c99f0-7881-4f2d-9675-c75cbdee3acd.jpg" width="250"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/d27c99f0-7881-4f2d-9675-c75cbdee3acd.jpg" width="250"/> </div><br>
```java
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
@ -45,4 +45,4 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -7,13 +7,13 @@
根据二叉树的前序遍历和中序遍历的结果重建出该二叉树假设输入的前序遍历和中序遍历的结果中都不含重复的数字
<div align="center"> <img src="pics/31d9adce-2af8-4754-8386-0aabb4e500b0.png" width="300"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/31d9adce-2af8-4754-8386-0aabb4e500b0.png" width="300"/> </div><br>
## 解题思路
前序遍历的第一个值为根节点的值使用这个值将中序遍历结果分成两部分左部分为树的左子树中序遍历结果右部分为树的右子树中序遍历的结果
<div align="center"> <img src="pics/c269e362-1128-4212-9cf3-d4c12b363b2f.gif" width="330px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c269e362-1128-4212-9cf3-d4c12b363b2f.gif" width="330px"> </div><br>
```java
// 缓存中序遍历数组每个值对应的索引
@ -42,4 +42,4 @@ private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int inL) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -24,11 +24,11 @@ public class TreeLinkNode {
如果一个节点的右子树不为空那么该节点的下一个节点是右子树的最左节点
<div align="center"> <img src="pics/b0611f89-1e5f-4494-a795-3544bf65042a.gif" width="220px"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b0611f89-1e5f-4494-a795-3544bf65042a.gif" width="220px"/> </div><br>
否则向上找第一个左链接指向的树包含该节点的祖先节点
<div align="center"> <img src="pics/95080fae-de40-463d-a76e-783a0c677fec.gif" width="200px"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/95080fae-de40-463d-a76e-783a0c677fec.gif" width="200px"/> </div><br>
```java
public TreeLinkNode GetNext(TreeLinkNode pNode) {
@ -54,4 +54,4 @@ public TreeLinkNode GetNext(TreeLinkNode pNode) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -10,7 +10,7 @@
in 栈用来处理入栈push操作out 栈用来处理出栈pop操作一个元素进入 in 栈之后出栈的顺序被反转当元素要出栈时需要先进入 out 此时元素出栈顺序再一次被反转因此出栈顺序就和最开始入栈顺序是相同的先进入的元素先退出这就是队列的顺序
<div align="center"> <img src="pics/3ea280b5-be7d-471b-ac76-ff020384357c.gif" width="350"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/3ea280b5-be7d-471b-ac76-ff020384357c.gif" width="350"/> </div><br>
```java
Stack<Integer> in = new Stack<Integer>();
@ -37,4 +37,4 @@ public int pop() throws Exception {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -14,13 +14,13 @@
Docker 主要解决环境配置问题它是一种虚拟化技术对进程进行隔离被隔离的进程独立于宿主操作系统和其它隔离的进程使用 Docker 可以不修改应用程序代码不需要开发人员学习特定环境下的技术就能够将现有的应用程序部署在其它机器上
<div align="center"> <img src="pics/011f3ef6-d824-4d43-8b2c-36dab8eaaa72-1.png" width="400px"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/011f3ef6-d824-4d43-8b2c-36dab8eaaa72-1.png" width="400px"/> </div><br>
# 与虚拟机的比较
虚拟机也是一种虚拟化技术它与 Docker 最大的区别在于它是通过模拟硬件并在硬件上安装操作系统来实现
<div align="center"> <img src="pics/be608a77-7b7f-4f8e-87cc-f2237270bf69.png" width="500"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/be608a77-7b7f-4f8e-87cc-f2237270bf69.png" width="500"/> </div><br>
## 启动速度
@ -74,7 +74,7 @@ Docker 轻量级的特点使得它很适合用于部署、维护、组合微服
构建容器时通过在镜像的基础上添加一个可写层writable layer用来保存着容器运行过程中的修改
<div align="center"> <img src="pics/docker-filesystems-busyboxrw.png"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/docker-filesystems-busyboxrw.png"/> </div><br>
# 参考资料
@ -93,4 +93,4 @@ Docker 轻量级的特点使得它很适合用于部署、维护、组合微服
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -18,7 +18,7 @@
Git 属于分布式版本控制系统 SVN 属于集中式
<div align="center"> <img src="pics/1fe2dc77-9a2d-4643-90b3-bbf50f649bac.png" width="600px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1fe2dc77-9a2d-4643-90b3-bbf50f649bac.png" width="600px"> </div><br>
集中式版本控制只有中心服务器拥有一份代码而分布式版本控制每个人的电脑上就有一份完整的代码
@ -40,45 +40,45 @@ Github 就是一个中心服务器。
Git 的版本库有一个称为 Stage 的暂存区以及最后的 History 版本库History 存储所有分支信息使用一个 HEAD 指针指向当前分支
<div align="center"> <img src="pics/71b97a50-a49f-4f1a-81d1-48c3364d61b3.png" width="700px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/71b97a50-a49f-4f1a-81d1-48c3364d61b3.png" width="700px"> </div><br>
- git add files 把文件的修改添加到暂存区
- git commit 把暂存区的修改提交到当前分支提交之后暂存区就被清空了
- git reset -- files 使用当前分支上的修改覆盖暂存区用来撤销最后一次 git add files
- git checkout -- files 使用暂存区的修改覆盖工作目录用来撤销本地修改
<div align="center"> <img src="pics/72ee7e9a-194d-42e9-b4d7-29c23417ca18.png" width="320px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/72ee7e9a-194d-42e9-b4d7-29c23417ca18.png" width="320px"> </div><br>
可以跳过暂存区域直接从分支中取出修改或者直接提交修改到分支中
- git commit -a 直接把所有文件的修改添加到暂存区然后执行提交
- git checkout HEAD -- files 取出最后一次修改可以用来进行回滚操作
<div align="center"> <img src="pics/a4a0a6e6-386b-4bfa-b899-ec33d3310f3e.png" width="500px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/a4a0a6e6-386b-4bfa-b899-ec33d3310f3e.png" width="500px"> </div><br>
# 分支实现
使用指针将每个提交连接成一条时间线HEAD 指针指向当前分支指针
<div align="center"> <img src="pics/ec4d7464-7140-46d8-827e-d63634202e1e.png" width="220px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ec4d7464-7140-46d8-827e-d63634202e1e.png" width="220px"> </div><br>
新建分支是新建一个指针指向时间线的最后一个节点并让 HEAD 指针指向新分支表示新分支成为当前分支
<div align="center"> <img src="pics/66d00642-ce37-466c-8f7a-143d0bf84cd6.png" width="220px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/66d00642-ce37-466c-8f7a-143d0bf84cd6.png" width="220px"> </div><br>
每次提交只会让当前分支指针向前移动而其它分支指针不会移动
<div align="center"> <img src="pics/72a01242-e6b4-46c5-a285-24e754d63093.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/72a01242-e6b4-46c5-a285-24e754d63093.png" width="300px"> </div><br>
合并分支也只需要改变指针即可
<div align="center"> <img src="pics/94617147-0cbd-4a28-847d-81e52efb1b1e.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/94617147-0cbd-4a28-847d-81e52efb1b1e.png" width="300px"> </div><br>
# 冲突
当两个分支都对同一个文件的同一行进行了修改在分支合并时就会产生冲突
<div align="center"> <img src="pics/32b05e81-41b3-414a-8656-736c9604e3d6.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/32b05e81-41b3-414a-8656-736c9604e3d6.png" width="300px"> </div><br>
Git 会使用 <<<<<<< ======= >>>>>>> 标记出不同分支的内容只需要把不同分支中冲突部分修改成一样就能解决冲突
@ -100,7 +100,7 @@ Creating a new branch is quick AND simple.
$ git merge --no-ff -m "merge with no-ff" dev
```
<div align="center"> <img src="pics/9a519773-84b2-4c81-81cf-4e7dd739a97a.png" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9a519773-84b2-4c81-81cf-4e7dd739a97a.png" width="350px"> </div><br>
# 分支管理策略
@ -108,7 +108,7 @@ master 分支应该是非常稳定的,只用来发布新版本;
日常开发在开发分支 dev 上进行
<div align="center"> <img src="pics/245fd2fb-209c-4ad5-bc5e-eb5664966a0e.jpg" width=""> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/245fd2fb-209c-4ad5-bc5e-eb5664966a0e.jpg" width=""> </div><br>
# 储藏Stashing
@ -148,7 +148,7 @@ $ ssh-keygen -t rsa -C "youremail@example.com"
# Git 命令一览
<div align="center"> <img src="pics/7a29acce-f243-4914-9f00-f2988c528412.jpg" width=""> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7a29acce-f243-4914-9f00-f2988c528412.jpg" width=""> </div><br>
比较详细的地址http://www.cheat-sheets.org/saved-copy/git-cheat-sheet.pdf
@ -164,4 +164,4 @@ $ ssh-keygen -t rsa -C "youremail@example.com"
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -62,17 +62,17 @@
URI 包含 URL URN
<div align="center"> <img src="pics/8441b2c4-dca7-4d6b-8efb-f22efccaf331.png" width="500px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/8441b2c4-dca7-4d6b-8efb-f22efccaf331.png" width="500px"> </div><br>
## 请求和响应报文
### 1. 请求报文
<div align="center"> <img src="pics/HTTP_RequestMessageExample.png" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/HTTP_RequestMessageExample.png" width=""/> </div><br>
### 2. 响应报文
<div align="center"> <img src="pics/HTTP_ResponseMessageExample.png" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/HTTP_ResponseMessageExample.png" width=""/> </div><br>
# HTTP 方法
@ -159,7 +159,7 @@ DELETE /file.html HTTP/1.1
CONNECT www.example.com:443 HTTP/1.1
```
<div align="center"> <img src="pics/dc00f70e-c5c8-4d20-baf1-2d70014a97e3.jpg" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/dc00f70e-c5c8-4d20-baf1-2d70014a97e3.jpg" width=""/> </div><br>
## TRACE
@ -302,7 +302,7 @@ CONNECT www.example.com:443 HTTP/1.1
## 连接管理
<div align="center"> <img src="pics/HTTP1_x_Connections.png" width="800"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/HTTP1_x_Connections.png" width="800"/> </div><br>
### 1. 短连接与长连接
@ -631,11 +631,11 @@ HTTP/1.1 使用虚拟主机技术,使得一台服务器拥有多个域名,
- 用户察觉得到正向代理的存在
<div align="center"> <img src="pics/a314bb79-5b18-4e63-a976-3448bffa6f1b.png" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/a314bb79-5b18-4e63-a976-3448bffa6f1b.png" width=""/> </div><br>
- 而反向代理一般位于内部网络中用户察觉不到
<div align="center"> <img src="pics/2d09a847-b854-439c-9198-b29c65810944.png" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2d09a847-b854-439c-9198-b29c65810944.png" width=""/> </div><br>
### 2. 网关
@ -657,7 +657,7 @@ HTTPS 并不是新协议,而是让 HTTP 先和 SSLSecure Sockets Layer
通过使用 SSLHTTPS 具有了加密防窃听认证防伪装和完整性保护防篡改
<div align="center"> <img src="pics/ssl-offloading.jpg" width="700"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ssl-offloading.jpg" width="700"/> </div><br>
## 加密
@ -668,7 +668,7 @@ HTTPS 并不是新协议,而是让 HTTP 先和 SSLSecure Sockets Layer
- 优点运算速度快
- 缺点无法安全地将密钥传输给通信方
<div align="center"> <img src="pics/7fffa4b8-b36d-471f-ad0c-a88ee763bb76.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7fffa4b8-b36d-471f-ad0c-a88ee763bb76.png" width="600"/> </div><br>
### 2.非对称密钥加密
@ -681,13 +681,13 @@ HTTPS 并不是新协议,而是让 HTTP 先和 SSLSecure Sockets Layer
- 优点可以更安全地将公开密钥传输给通信发送方
- 缺点运算速度慢
<div align="center"> <img src="pics/39ccb299-ee99-4dd1-b8b4-2f9ec9495cb4.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/39ccb299-ee99-4dd1-b8b4-2f9ec9495cb4.png" width="600"/> </div><br>
### 3. HTTPS 采用的加密方式
HTTPS 采用混合的加密机制使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性之后使用对称密钥加密进行通信来保证通信过程的效率下图中的 Session Key 就是对称密钥
<div align="center"> <img src="pics/How-HTTPS-Works.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/How-HTTPS-Works.png" width="600"/> </div><br>
## 认证
@ -699,7 +699,7 @@ HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对
进行 HTTPS 通信时服务器会把证书发送给客户端客户端取得其中的公开密钥之后先使用数字签名进行验证如果验证通过就可以开始通信了
<div align="center"> <img src="pics/2017-06-11-ca.png" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2017-06-11-ca.png" width=""/> </div><br>
## 完整性保护
@ -728,7 +728,7 @@ HTTP/1.x 实现简单是以牺牲性能为代价的:
HTTP/2.0 将报文分成 HEADERS 帧和 DATA 它们都是二进制格式的
<div align="center"> <img src="pics/86e6a91d-a285-447a-9345-c5484b8d0c47.png" width="400"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/86e6a91d-a285-447a-9345-c5484b8d0c47.png" width="400"/> </div><br>
在通信过程中只会有一个 TCP 连接存在它承载了任意数量的双向数据流Stream
@ -736,13 +736,13 @@ HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式
- 消息Message是与逻辑请求或响应对应的完整的一系列帧
- Frame是最小的通信单位来自不同数据流的帧可以交错发送然后再根据每个帧头的数据流标识符重新组装
<div align="center"> <img src="pics/af198da1-2480-4043-b07f-a3b91a88b815.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/af198da1-2480-4043-b07f-a3b91a88b815.png" width="600"/> </div><br>
## 服务端推送
HTTP/2.0 在客户端请求一个资源时会把相关的资源一起发送给客户端客户端就不需要再次发起请求了例如客户端请求 page.html 页面服务端就把 script.js style.css 等与之相关的资源一起发给客户端
<div align="center"> <img src="pics/e3f1657c-80fc-4dfa-9643-bf51abd201c6.png" width="800"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e3f1657c-80fc-4dfa-9643-bf51abd201c6.png" width="800"/> </div><br>
## 首部压缩
@ -752,7 +752,7 @@ HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见
不仅如此HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩
<div align="center"> <img src="pics/_u4E0B_u8F7D.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/_u4E0B_u8F7D.png" width="600"/> </div><br>
# HTTP/1.1 新特性
@ -883,4 +883,4 @@ DELETE /idX/delete HTTP/1.1 -> Returns 404
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -97,7 +97,7 @@ Java I/O 使用了装饰者模式来实现。以 InputStream 为例,
- FileInputStream InputStream 的子类属于具体组件提供了字节流的输入操作
- FilterInputStream 属于抽象装饰者装饰者用于装饰组件为组件提供额外的功能例如 BufferedInputStream FileInputStream 提供缓存的功能
<div align="center"> <img src="pics/9709694b-db05-4cce-8d2f-1c8b09f4d921.png" width="650px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9709694b-db05-4cce-8d2f-1c8b09f4d921.png" width="650px"> </div><br>
实例化一个具有缓存功能的字节流对象时只需要在 FileInputStream 对象上再套一层 BufferedInputStream 对象即可
@ -277,7 +277,7 @@ public static void main(String[] args) throws IOException {
- Socket客户端类
- 服务器和客户端通过 InputStream OutputStream 进行输入输出
<div align="center"> <img src="pics/1e6affc4-18e5-4596-96ef-fb84c63bf88a.png" width="550px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1e6affc4-18e5-4596-96ef-fb84c63bf88a.png" width="550px"> </div><br>
## Datagram
@ -339,23 +339,23 @@ I/O 包和 NIO 已经很好地集成了java.io.\* 已经以 NIO 为基础重
新建一个大小为 8 个字节的缓冲区此时 position 0 limit = capacity = 8capacity 变量不会改变下面的讨论会忽略它
<div align="center"> <img src="pics/1bea398f-17a7-4f67-a90b-9e2d243eaa9a.png"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1bea398f-17a7-4f67-a90b-9e2d243eaa9a.png"/> </div><br>
从输入通道中读取 5 个字节数据写入缓冲区中此时 position 5limit 保持不变
<div align="center"> <img src="pics/80804f52-8815-4096-b506-48eef3eed5c6.png"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/80804f52-8815-4096-b506-48eef3eed5c6.png"/> </div><br>
在将缓冲区的数据写到输出通道之前需要先调用 flip() 方法这个方法将 limit 设置为当前 position并将 position 设置为 0
<div align="center"> <img src="pics/952e06bd-5a65-4cab-82e4-dd1536462f38.png"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/952e06bd-5a65-4cab-82e4-dd1536462f38.png"/> </div><br>
从缓冲区中取 4 个字节到输出缓冲中此时 position 设为 4
<div align="center"> <img src="pics/b5bdcbe2-b958-4aef-9151-6ad963cb28b4.png"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b5bdcbe2-b958-4aef-9151-6ad963cb28b4.png"/> </div><br>
最后需要调用 clear() 方法来清空缓冲区此时 position limit 都被设置为最初位置
<div align="center"> <img src="pics/67bf5487-c45d-49b6-b9c0-a058d8c68902.png"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/67bf5487-c45d-49b6-b9c0-a058d8c68902.png"/> </div><br>
## 文件 NIO 实例
@ -413,7 +413,7 @@ NIO 实现了 IO 多路复用中的 Reactor 模型,一个线程 Thread 使用
应该注意的是只有套接字 Channel 才能配置为非阻塞 FileChannel 不能 FileChannel 配置非阻塞也没有意义
<div align="center"> <img src="pics/093f9e57-429c-413a-83ee-c689ba596cef.png" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/093f9e57-429c-413a-83ee-c689ba596cef.png" width="350px"> </div><br>
### 1. 创建选择器
@ -624,4 +624,4 @@ NIO 与普通 I/O 的区别主要有以下两点:
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -193,7 +193,7 @@ value 数组被声明为 final这意味着 value 数组初始化之后就不
如果一个 String 对象已经被创建过了那么就会从 String Pool 中取得引用只有 String 是不可变的才可能使用 String Pool
<div align="center"> <img src="pics/9112288f-23f5-4e53-b222-a46fdbca1603.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9112288f-23f5-4e53-b222-a46fdbca1603.png" width="300px"> </div><br>
**3. 安全性**
@ -1356,7 +1356,7 @@ Throwable 可以用来表示任何可以作为异常抛出的类,分为两种
- **受检异常** 需要用 try...catch... 语句捕获并进行处理并且可以从异常中恢复
- **非受检异常** 是程序运行时错误例如除 0 会引发 Arithmetic Exception此时程序崩溃并且无法恢复
<div align="center"> <img src="pics/PPjwP.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/PPjwP.png" width="600"/> </div><br>
- [Java 入门之异常处理](https://www.tianmaying.com/tutorial/Java-Exception)
- [Java 异常的面试问题及答案 -Part 1](http://www.importnew.com/7383.html)
@ -1438,4 +1438,4 @@ Java 注解是附加在代码中的一些元信息,用于一些工具在编译
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -24,7 +24,7 @@
## Collection
<div align="center"> <img src="pics/73403d84-d921-49f1-93a9-d8fe050f3497.png" width="800px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/73403d84-d921-49f1-93a9-d8fe050f3497.png" width="800px"> </div><br>
### 1. Set
@ -50,7 +50,7 @@
## Map
<div align="center"> <img src="pics/774d756b-902a-41a3-a3fd-81ca3ef688dc.png" width="500px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/774d756b-902a-41a3-a3fd-81ca3ef688dc.png" width="500px"> </div><br>
- TreeMap基于红黑树实现
@ -65,7 +65,7 @@
## 迭代器模式
<div align="center"> <img src="pics/93fb1d38-83f9-464a-a733-67b2e6bfddda.png" width="600px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/93fb1d38-83f9-464a-a733-67b2e6bfddda.png" width="600px"> </div><br>
Collection 继承了 Iterable 接口其中的 iterator() 方法能够产生一个 Iterator 对象通过这个对象就可以迭代遍历 Collection 中的元素
@ -126,7 +126,7 @@ public class ArrayList<E> extends AbstractList<E>
private static final int DEFAULT_CAPACITY = 10;
```
<div align="center"> <img src="pics/52a7744f-5bce-4ff3-a6f0-8449334d9f3d.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/52a7744f-5bce-4ff3-a6f0-8449334d9f3d.png" width="400px"> </div><br>
### 2. 扩容
@ -430,7 +430,7 @@ transient Node<E> first;
transient Node<E> last;
```
<div align="center"> <img src="pics/c8563120-cb00-4dd6-9213-9d9b337a7f7c.png" width="500px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c8563120-cb00-4dd6-9213-9d9b337a7f7c.png" width="500px"> </div><br>
### 2. ArrayList 的比较
@ -452,7 +452,7 @@ transient Entry[] table;
Entry 存储着键值对它包含了四个字段 next 字段我们可以看出 Entry 是一个链表即数组中的每个位置被当成一个桶一个桶存放一个链表HashMap 使用拉链法来解决冲突同一个链表中存放哈希值和散列桶取模运算结果相同的 Entry
<div align="center"> <img src="pics/9420a703-1f9d-42ce-808e-bcb82b56483d.png" width="550px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9420a703-1f9d-42ce-808e-bcb82b56483d.png" width="550px"> </div><br>
```java
static class Entry<K,V> implements Map.Entry<K,V> {
@ -528,7 +528,7 @@ map.put("K3", "V3");
- 计算键值对所在的桶
- 在链表上顺序查找时间复杂度显然和链表的长度成正比
<div align="center"> <img src="pics/e0870f80-b79e-4542-ae39-7420d4b0d8fe.png" width="550px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e0870f80-b79e-4542-ae39-7420d4b0d8fe.png" width="550px"> </div><br>
### 3. put 操作
@ -864,7 +864,7 @@ final Segment<K,V>[] segments;
static final int DEFAULT_CONCURRENCY_LEVEL = 16;
```
<div align="center"> <img src="pics/db808eff-31d7-4229-a4ad-b8ae71870a3a.png" width="550px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/db808eff-31d7-4229-a4ad-b8ae71870a3a.png" width="550px"> </div><br>
### 2. size 操作
@ -1156,4 +1156,4 @@ public final class ConcurrentCache<K, V> {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -61,7 +61,7 @@
# 线程状态转换
<div align="center"> <img src="pics/adfb427d-3b21-40d7-a142-757f4ed73079.png" width="600px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/adfb427d-3b21-40d7-a142-757f4ed73079.png" width="600px"> </div><br>
## 新建New
@ -736,7 +736,7 @@ java.util.concurrentJ.U.C大大提高了并发性能AQS 被认为是 J.
维护了一个计数器 cnt每次调用 countDown() 方法会让计数器的值减 1减到 0 的时候那些因为调用 await() 方法而在等待的线程就会被唤醒
<div align="center"> <img src="pics/ba078291-791e-4378-b6d1-ece76c2f0b14.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ba078291-791e-4378-b6d1-ece76c2f0b14.png" width="300px"> </div><br>
```java
public class CountdownLatchExample {
@ -785,7 +785,7 @@ public CyclicBarrier(int parties) {
}
```
<div align="center"> <img src="pics/f71af66b-0d54-4399-a44b-f47b58321984.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f71af66b-0d54-4399-a44b-f47b58321984.png" width="300px"> </div><br>
```java
public class CyclicBarrierExample {
@ -1022,7 +1022,7 @@ public class ForkJoinPool extends AbstractExecutorService
ForkJoinPool 实现了工作窃取算法来提高 CPU 的利用率每个线程都维护了一个双端队列用来存储需要执行的任务工作窃取算法允许空闲的线程从其它线程的双端队列中窃取一个任务来执行窃取的任务必须是最晚的任务避免和队列所属线程发生竞争例如下图中Thread2 Thread1 的队列中拿出最晚的 Task1 任务Thread1 会拿出 Task2 来执行这样就避免发生竞争但是如果队列中只有一个任务时还是会发生竞争
<div align="center"> <img src="pics/e42f188f-f4a9-4e6f-88fc-45f4682072fb.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e42f188f-f4a9-4e6f-88fc-45f4682072fb.png" width="300px"> </div><br>
# 线程不安全示例
@ -1077,19 +1077,19 @@ Java 内存模型试图屏蔽各种硬件和操作系统的内存访问差异,
加入高速缓存带来了一个新的问题缓存一致性如果多个缓存共享同一块主内存区域那么多个缓存的数据可能会不一致需要一些协议来解决这个问题
<div align="center"> <img src="pics/942ca0d2-9d5c-45a4-89cb-5fd89b61913f.png" width="600px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/942ca0d2-9d5c-45a4-89cb-5fd89b61913f.png" width="600px"> </div><br>
所有的变量都存储在主内存中每个线程还有自己的工作内存工作内存存储在高速缓存或者寄存器中保存了该线程使用的变量的主内存副本拷贝
线程只能直接操作工作内存中的变量不同线程之间的变量值传递需要通过主内存来完成
<div align="center"> <img src="pics/15851555-5abc-497d-ad34-efed10f43a6b.png" width="600px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/15851555-5abc-497d-ad34-efed10f43a6b.png" width="600px"> </div><br>
## 内存间交互操作
Java 内存模型定义了 8 个操作来完成主内存和工作内存的交互操作
<div align="center"> <img src="pics/8b7ebbad-9604-4375-84e3-f412099d170c.png" width="450px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/8b7ebbad-9604-4375-84e3-f412099d170c.png" width="450px"> </div><br>
- read把一个变量的值从主内存传输到工作内存中
- load read 之后执行 read 得到的值放入工作内存的变量副本中
@ -1112,11 +1112,11 @@ Java 内存模型保证了 read、load、use、assign、store、write、lock 和
下图演示了两个线程同时对 cnt 进行操作loadassignstore 这一系列操作整体上看不具备原子性那么在 T1 修改 cnt 并且还没有将修改后的值写入主内存T2 依然可以读入旧值可以看出这两个线程虽然执行了两次自增运算但是主内存中 cnt 的值最后为 1 而不是 2因此对 int 类型读写操作满足原子性只是说明 loadassignstore 这些单个操作具备原子性
<div align="center"> <img src="pics/2797a609-68db-4d7b-8701-41ac9a34b14f.jpg" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2797a609-68db-4d7b-8701-41ac9a34b14f.jpg" width="300px"> </div><br>
AtomicInteger 能保证多个线程修改的原子性
<div align="center"> <img src="pics/dd563037-fcaa-4bd8-83b6-b39d93a12c77.jpg" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/dd563037-fcaa-4bd8-83b6-b39d93a12c77.jpg" width="300px"> </div><br>
使用 AtomicInteger 重写之前线程不安全的代码之后得到以下线程安全实现
@ -1224,7 +1224,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即
在一个线程内在程序前面的操作先行发生于后面的操作
<div align="center"> <img src="pics/874b3ff7-7c5c-4e7a-b8ab-a82a3e038d20.png" width="180px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/874b3ff7-7c5c-4e7a-b8ab-a82a3e038d20.png" width="180px"> </div><br>
### 2. 管程锁定规则
@ -1232,7 +1232,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即
一个 unlock 操作先行发生于后面对同一个锁的 lock 操作
<div align="center"> <img src="pics/8996a537-7c4a-4ec8-a3b7-7ef1798eae26.png" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/8996a537-7c4a-4ec8-a3b7-7ef1798eae26.png" width="350px"> </div><br>
### 3. volatile 变量规则
@ -1240,7 +1240,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即
对一个 volatile 变量的写操作先行发生于后面对这个变量的读操作
<div align="center"> <img src="pics/942f33c9-8ad9-4987-836f-007de4c21de0.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/942f33c9-8ad9-4987-836f-007de4c21de0.png" width="400px"> </div><br>
### 4. 线程启动规则
@ -1248,7 +1248,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即
Thread 对象的 start() 方法调用先行发生于此线程的每一个动作
<div align="center"> <img src="pics/6270c216-7ec0-4db7-94de-0003bce37cd2.png" width="380px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/6270c216-7ec0-4db7-94de-0003bce37cd2.png" width="380px"> </div><br>
### 5. 线程加入规则
@ -1256,7 +1256,7 @@ Thread 对象的 start() 方法调用先行发生于此线程的每一个动作
Thread 对象的结束先行发生于 join() 方法返回
<div align="center"> <img src="pics/233f8d89-31d7-413f-9c02-042f19c46ba1.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/233f8d89-31d7-413f-9c02-042f19c46ba1.png" width="400px"> </div><br>
### 6. 线程中断规则
@ -1474,7 +1474,7 @@ public class ThreadLocalExample1 {
它所对应的底层结构图为
<div align="center"> <img src="pics/6782674c-1bfe-4879-af39-e9d722a95d39.png" width="500px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/6782674c-1bfe-4879-af39-e9d722a95d39.png" width="500px"> </div><br>
每个 Thread 都有一个 ThreadLocal.ThreadLocalMap 对象
@ -1577,17 +1577,17 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态:
以下是 HotSpot 虚拟机对象头的内存布局这些数据被称为 Mark Word其中 tag bits 对应了五个状态这些状态在右侧的 state 表格中给出除了 marked for gc 状态其它四个状态已经在前面介绍过了
<div align="center"> <img src="pics/bb6a49be-00f2-4f27-a0ce-4ed764bc605c.png" width="500"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/bb6a49be-00f2-4f27-a0ce-4ed764bc605c.png" width="500"/> </div><br>
下图左侧是一个线程的虚拟机栈其中有一部分称为 Lock Record 的区域这是在轻量级锁运行过程创建的用于存放锁对象的 Mark Word而右侧就是一个锁对象包含了 Mark Word 和其它信息
<div align="center"> <img src="pics/051e436c-0e46-4c59-8f67-52d89d656182.png" width="500"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/051e436c-0e46-4c59-8f67-52d89d656182.png" width="500"/> </div><br>
轻量级锁是相对于传统的重量级锁而言它使用 CAS 操作来避免重量级锁使用互斥量的开销对于绝大部分的锁在整个同步周期内都是不存在竞争的因此也就不需要都使用互斥量进行同步可以先采用 CAS 操作进行同步如果 CAS 失败了再改用互斥量进行同步
当尝试获取一个锁对象时如果锁对象标记为 0 01说明锁对象的锁未锁定unlocked状态此时虚拟机在当前线程的虚拟机栈中创建 Lock Record然后使用 CAS 操作将对象的 Mark Word 更新为 Lock Record 指针如果 CAS 操作成功了那么线程就获取了该对象上的锁并且对象的 Mark Word 的锁标记变为 00表示该对象处于轻量级锁状态
<div align="center"> <img src="pics/baaa681f-7c52-4198-a5ae-303b9386cf47.png" width="400"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/baaa681f-7c52-4198-a5ae-303b9386cf47.png" width="400"/> </div><br>
如果 CAS 操作失败了虚拟机首先会检查对象的 Mark Word 是否指向当前线程的虚拟机栈如果是的话说明当前线程已经拥有了这个锁对象那就可以直接进入同步块继续执行否则说明这个锁对象已经被其他线程线程抢占了如果有两条以上的线程争用同一个锁那轻量级锁就不再有效要膨胀为重量级锁
@ -1599,7 +1599,7 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态:
当有另外一个线程去尝试获取这个锁对象时偏向状态就宣告结束此时撤销偏向Revoke Bias后恢复到未锁定状态或者轻量级锁状态
<div align="center"> <img src="pics/390c913b-5f31-444f-bbdb-2b88b688e7ce.jpg" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/390c913b-5f31-444f-bbdb-2b88b688e7ce.jpg" width="600"/> </div><br>
# 十三多线程开发良好的实践
@ -1640,4 +1640,4 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态:
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -32,7 +32,7 @@
# 运行时数据区域
<div align="center"> <img src="pics/5778d113-8e13-4c53-b5bf-801e58080b97.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/5778d113-8e13-4c53-b5bf-801e58080b97.png" width="400px"> </div><br>
## 程序计数器
@ -42,7 +42,7 @@
每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表操作数栈常量池引用等信息从方法调用直至执行完成的过程对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程
<div align="center"> <img src="pics/8442519f-0b4d-48f4-8229-56f984363c69.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/8442519f-0b4d-48f4-8229-56f984363c69.png" width="400px"> </div><br>
可以通过 -Xss 这个虚拟机参数来指定每个线程的 Java 虚拟机栈内存大小 JDK 1.4 中默认为 256K而在 JDK 1.5+ 默认为 1M
@ -61,7 +61,7 @@ java -Xss2M HackTheJava
本地方法一般是用其它语言CC++ 或汇编语言等编写的并且被编译为基于本机硬件和操作系统的程序对待这些方法需要特别处理
<div align="center"> <img src="pics/66a6899d-c6b0-4a47-8569-9d08f0baf86c.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/66a6899d-c6b0-4a47-8569-9d08f0baf86c.png" width="300px"> </div><br>
##
@ -146,7 +146,7 @@ Java 虚拟机使用该算法来判断对象是否可被回收GC Roots 一般
- 方法区中类静态属性引用的对象
- 方法区中的常量引用的对象
<div align="center"> <img src="pics/83d909d2-3858-4fe1-8ff4-16471db0b180.png" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/83d909d2-3858-4fe1-8ff4-16471db0b180.png" width="350px"> </div><br>
### 3. 方法区的回收
@ -227,7 +227,7 @@ obj = null;
### 1. 标记 - 清除
<div align="center"> <img src="pics/005b481b-502b-4e3f-985d-d043c2b330aa.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/005b481b-502b-4e3f-985d-d043c2b330aa.png" width="400px"> </div><br>
在标记阶段程序会检查每个对象是否为活动对象如果是活动对象则程序会在对象头部打上标记
@ -242,7 +242,7 @@ obj = null;
### 2. 标记 - 整理
<div align="center"> <img src="pics/ccd773a5-ad38-4022-895c-7ac318f31437.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ccd773a5-ad38-4022-895c-7ac318f31437.png" width="400px"> </div><br>
让所有存活的对象都向一端移动然后直接清理掉端边界以外的内存
@ -256,7 +256,7 @@ obj = null;
### 3. 复制
<div align="center"> <img src="pics/b2b77b9e-958c-4016-8ae5-9c6edd83871e.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b2b77b9e-958c-4016-8ae5-9c6edd83871e.png" width="400px"> </div><br>
将内存划分为大小相等的两块每次只使用其中一块当这一块内存用完了就将还存活的对象复制到另一块上面然后再把使用过的内存空间进行一次清理
@ -277,7 +277,7 @@ HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1保证了内
## 垃圾收集器
<div align="center"> <img src="pics/c625baa0-dde6-449e-93df-c3a67f2f430f.jpg" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c625baa0-dde6-449e-93df-c3a67f2f430f.jpg" width=""/> </div><br>
以上是 HotSpot 虚拟机中的 7 个垃圾收集器连线表示垃圾收集器可以配合使用
@ -286,7 +286,7 @@ HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1保证了内
### 1. Serial 收集器
<div align="center"> <img src="pics/22fda4ae-4dd5-489d-ab10-9ebfdad22ae0.jpg" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/22fda4ae-4dd5-489d-ab10-9ebfdad22ae0.jpg" width=""/> </div><br>
Serial 翻译为串行也就是说它以串行的方式执行
@ -298,7 +298,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。
### 2. ParNew 收集器
<div align="center"> <img src="pics/81538cd5-1bcf-4e31-86e5-e198df1e013b.jpg" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/81538cd5-1bcf-4e31-86e5-e198df1e013b.jpg" width=""/> </div><br>
它是 Serial 收集器的多线程版本
@ -318,7 +318,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。
### 4. Serial Old 收集器
<div align="center"> <img src="pics/08f32fd3-f736-4a67-81ca-295b2a7972f2.jpg" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/08f32fd3-f736-4a67-81ca-295b2a7972f2.jpg" width=""/> </div><br>
Serial 收集器的老年代版本也是给 Client 场景下的虚拟机使用如果用在 Server 场景下它有两大用途
@ -327,7 +327,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。
### 5. Parallel Old 收集器
<div align="center"> <img src="pics/278fe431-af88-4a95-a895-9c3b80117de3.jpg" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/278fe431-af88-4a95-a895-9c3b80117de3.jpg" width=""/> </div><br>
Parallel Scavenge 收集器的老年代版本
@ -335,7 +335,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。
### 6. CMS 收集器
<div align="center"> <img src="pics/62e77997-6957-4b68-8d12-bfd609bb2c68.jpg" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/62e77997-6957-4b68-8d12-bfd609bb2c68.jpg" width=""/> </div><br>
CMSConcurrent Mark SweepMark Sweep 指的是标记 - 清除算法
@ -360,17 +360,17 @@ G1Garbage-First它是一款面向服务端应用的垃圾收集器
堆被分为新生代和老年代其它收集器进行收集的范围都是整个新生代或者老年代 G1 可以直接对新生代和老年代一起回收
<div align="center"> <img src="pics/4cf711a8-7ab2-4152-b85c-d5c226733807.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/4cf711a8-7ab2-4152-b85c-d5c226733807.png" width="600"/> </div><br>
G1 把堆划分成多个大小相等的独立区域Region新生代和老年代不再物理隔离
<div align="center"> <img src="pics/9bbddeeb-e939-41f0-8e8e-2b1a0aa7e0a7.png" width="600"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9bbddeeb-e939-41f0-8e8e-2b1a0aa7e0a7.png" width="600"/> </div><br>
通过引入 Region 的概念从而将原来的一整块内存空间划分成多个的小空间使得每个小空间可以单独进行垃圾回收这种划分方法带来了很大的灵活性使得可预测的停顿时间模型成为可能通过记录每个 Region 垃圾回收时间以及回收所获得的空间这两个值是通过过去回收的经验获得并维护一个优先列表每次根据允许的收集时间优先回收价值最大的 Region
每个 Region 都有一个 Remembered Set用来记录该 Region 对象的引用对象所在的 Region通过使用 Remembered Set在做可达性分析的时候就可以避免全堆扫描
<div align="center"> <img src="pics/f99ee771-c56f-47fb-9148-c0036695b5fe.jpg" width=""/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f99ee771-c56f-47fb-9148-c0036695b5fe.jpg" width=""/> </div><br>
如果不计算维护 Remembered Set 的操作G1 收集器的运作大致可划分为以下几个步骤
@ -458,7 +458,7 @@ G1 把堆划分成多个大小相等的独立区域Region新生代和
## 类的生命周期
<div align="center"> <img src="pics/335fe19c-4a76-45ab-9320-88c90d6a0d7e.png" width="600px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/335fe19c-4a76-45ab-9320-88c90d6a0d7e.png" width="600px"> </div><br>
包括以下 7 个阶段
@ -628,7 +628,7 @@ System.out.println(ConstClass.HELLOWORLD);
下图展示了类加载器之间的层次关系称为双亲委派模型Parents Delegation Model该模型要求除了顶层的启动类加载器外其它的类加载器都要有自己的父类加载器这里的父子关系一般通过组合关系Composition来实现而不是继承关系Inheritance
<div align="center"> <img src="pics/0dd2d40a-5b2b-4d45-b176-e75a4cd4bdbf.png" width="500px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/0dd2d40a-5b2b-4d45-b176-e75a4cd4bdbf.png" width="500px"> </div><br>
### 1. 工作过程
@ -759,4 +759,4 @@ public class FileSystemClassLoader extends ClassLoader {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -307,4 +307,4 @@ private int binarySearch(int[] nums, int target) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -446,4 +446,4 @@ public int[] countBits(int num) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -114,4 +114,4 @@ private List<TreeNode> generateSubtrees(int s, int e) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -60,7 +60,7 @@
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=dp[i-1]+dp[i-2]" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/14fe1e71-8518-458f-a220-116003061a83.png" width="200px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/14fe1e71-8518-458f-a220-116003061a83.png" width="200px"> </div><br>
考虑到 dp[i] 只与 dp[i - 1] dp[i - 2] 有关因此可以只用两个变量来存储 dp[i - 1] dp[i - 2]使得原来的 O(N) 空间复杂度优化为 O(1) 复杂度
@ -93,7 +93,7 @@ public int climbStairs(int n) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=max(dp[i-2]+nums[i],dp[i-1])" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/2de794ca-aa7b-48f3-a556-a0e2708cb976.jpg" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2de794ca-aa7b-48f3-a556-a0e2708cb976.jpg" width="350px"> </div><br>
```java
public int rob(int[] nums) {
@ -149,7 +149,7 @@ private int rob(int[] nums, int first, int last) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=(i-1)*dp[i-2]+(i-1)*dp[i-1]" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/da1f96b9-fd4d-44ca-8925-fb14c5733388.png" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/da1f96b9-fd4d-44ca-8925-fb14c5733388.png" width="350px"> </div><br>
## 5. 母牛生产
@ -161,7 +161,7 @@ private int rob(int[] nums, int first, int last) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=dp[i-1]+dp[i-3]" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/879814ee-48b5-4bcb-86f5-dcc400cb81ad.png" width="250px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/879814ee-48b5-4bcb-86f5-dcc400cb81ad.png" width="250px"> </div><br>
# 矩阵路径
@ -211,7 +211,7 @@ public int minPathSum(int[][] grid) {
题目描述统计从矩阵左上角到右下角的路径总数每次只能向右或者向下移动
<div align="center"> <img src="pics/dc82f0f3-c1d4-4ac8-90ac-d5b32a9bd75a.jpg" width=""> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/dc82f0f3-c1d4-4ac8-90ac-d5b32a9bd75a.jpg" width=""> </div><br>
```java
public int uniquePaths(int m, int n) {
@ -442,7 +442,7 @@ public int numDecodings(String s) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[n]=max\{1,dp[i]+1|S_i<S_n\&\&i<n\}" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/ee994da4-0fc7-443d-ac56-c08caf00a204.jpg" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ee994da4-0fc7-443d-ac56-c08caf00a204.jpg" width="350px"> </div><br>
对于一个长度为 N 的序列最长递增子序列并不一定会以 S<sub>N</sub> 为结尾因此 dp[N] 不是序列的最长递增子序列的长度需要遍历 dp 数组找出最大值才是所要的结果max{ dp[i] | 1 <= i <= N} 即为所求
@ -615,7 +615,7 @@ public int wiggleMaxLength(int[] nums) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i][j]=\left\{\begin{array}{rcl}dp[i-1][j-1]&&{S1_i==S2_j}\\max(dp[i-1][j],dp[i][j-1])&&{S1_i<>S2_j}\end{array}\right." class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/ecd89a22-c075-4716-8423-e0ba89230e9a.jpg" width="450px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ecd89a22-c075-4716-8423-e0ba89230e9a.jpg" width="450px"> </div><br>
对于长度为 N 的序列 S<sub>1</sub> 和长度为 M 的序列 S<sub>2</sub>dp[N][M] 就是序列 S<sub>1</sub> 和序列 S<sub>2</sub> 的最长公共子序列长度
@ -655,7 +655,7 @@ public int lengthOfLCS(int[] nums1, int[] nums2) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+v)" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/8cb2be66-3d47-41ba-b55b-319fc68940d4.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/8cb2be66-3d47-41ba-b55b-319fc68940d4.png" width="400px"> </div><br>
```java
// W 为背包总体积
@ -684,7 +684,7 @@ public int knapsack(int W, int N, int[] weights, int[] values) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[j]=max(dp[j],dp[j-w]+v)" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/9ae89f16-7905-4a6f-88a2-874b4cac91f4.jpg" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9ae89f16-7905-4a6f-88a2-874b4cac91f4.jpg" width="300px"> </div><br>
因为 dp[j-w] 表示 dp[i-1][j-w]因此不能先求 dp[i][j-w]防止将 dp[i-1][j-w] 覆盖也就是说要先计算 dp[i][j] 再计算 dp[i][j-w]在程序实现时需要按倒序来循环求解
@ -1048,7 +1048,7 @@ public int combinationSum4(int[] nums, int target) {
题目描述交易之后需要有一天的冷却时间
<div align="center"> <img src="pics/ffd96b99-8009-487c-8e98-11c9d44ef14f.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ffd96b99-8009-487c-8e98-11c9d44ef14f.png" width="300px"> </div><br>
```java
public int maxProfit(int[] prices) {
@ -1091,7 +1091,7 @@ The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
题目描述每交易一次都要支付一定的费用
<div align="center"> <img src="pics/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png" width="300px"> </div><br>
```java
public int maxProfit(int[] prices, int fee) {
@ -1309,4 +1309,4 @@ public int minSteps(int n) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -32,7 +32,7 @@ Output: index1=1, index2=2
数组中的元素最多遍历一次时间复杂度为 O(N)只使用了两个额外变量空间复杂度为 O(1)
<div align="center"> <img src="pics/437cb54c-5970-4ba9-b2ef-2541f7d6c81e.gif" width="200px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/437cb54c-5970-4ba9-b2ef-2541f7d6c81e.gif" width="200px"> </div><br>
```java
public int[] twoSum(int[] numbers, int target) {
@ -102,7 +102,7 @@ Explanation: 1 * 1 + 2 * 2 = 5
Given s = "leetcode", return "leotcede".
```
<div align="center"> <img src="pics/a7cb8423-895d-4975-8ef8-662a0029c772.png" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/a7cb8423-895d-4975-8ef8-662a0029c772.png" width="400px"> </div><br>
使用双指针一个指针从头向尾遍历一个指针从尾到头遍历当两个指针都遍历到元音字符时交换这两个元音字符
@ -111,7 +111,7 @@ Given s = "leetcode", return "leotcede".
- 时间复杂度为 O(N)只需要遍历所有元素一次
- 空间复杂度 O(1)只需要使用两个额外变量
<div align="center"> <img src="pics/ef25ff7c-0f63-420d-8b30-eafbeea35d11.gif" width="400px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ef25ff7c-0f63-420d-8b30-eafbeea35d11.gif" width="400px"> </div><br>
```java
private final static HashSet<Character> vowels = new HashSet<>(
@ -155,7 +155,7 @@ Explanation: You could delete the character 'c'.
使用双指针可以很容易判断一个字符串是否是回文字符串令一个指针从左到右遍历一个指针从右到左遍历这两个指针同时移动一个位置每次都判断两个指针指向的字符是否相同如果都相同字符串才是具有左右对称性质的回文字符串
<div align="center"> <img src="pics/fcc941ec-134b-4dcd-bc86-1702fd305300.gif" width="250px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/fcc941ec-134b-4dcd-bc86-1702fd305300.gif" width="250px"> </div><br>
本题的关键是处理删除一个字符在使用双指针遍历字符串时如果出现两个指针指向的字符不相等的情况我们就试着删除一个字符再判断删除完之后的字符串是否是回文字符串
@ -163,7 +163,7 @@ Explanation: You could delete the character 'c'.
在试着删除字符时我们既可以删除左指针指向的字符也可以删除右指针指向的字符
<div align="center"> <img src="pics/db5f30a7-8bfa-4ecc-ab5d-747c77818964.gif" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/db5f30a7-8bfa-4ecc-ab5d-747c77818964.gif" width="300px"> </div><br>
```java
public boolean validPalindrome(String s) {
@ -296,4 +296,4 @@ private boolean isSubstr(String s, String target) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -137,4 +137,4 @@ private int maxCount(Map<Integer, Integer> countForNum) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -269,4 +269,4 @@ private class UF {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -241,4 +241,4 @@ public int countBinarySubstrings(String s) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -200,7 +200,7 @@ public String frequencySort(String s) {
有三种颜色的球算法的目标是将这三种球按颜色顺序正确地排列它其实是三向切分快速排序的一种变种在三向切分快速排序中每次切分都将数组分成三个区间小于切分元素等于切分元素大于切分元素而该算法是将数组分成三个区间等于红色等于白色等于蓝色
<div align="center"> <img src="pics/7a3215ec-6fb7-4935-8b0d-cb408208f7cb.png"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7a3215ec-6fb7-4935-8b0d-cb408208f7cb.png"/> </div><br>
## 1. 按颜色进行排序
@ -242,4 +242,4 @@ private void swap(int[] nums, int i, int j) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -32,7 +32,7 @@
# BFS
<div align="center"> <img src="pics/95903878-725b-4ed9-bded-bc4aae0792a9.jpg"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/95903878-725b-4ed9-bded-bc4aae0792a9.jpg"/> </div><br>
广度优先搜索一层一层地进行遍历每层遍历都以上一层遍历的结果作为起点遍历一个距离能访问到的所有节点需要注意的是遍历过的节点不能再次被遍历
@ -269,7 +269,7 @@ private int getShortestPath(List<Integer>[] graphic, int start, int end) {
# DFS
<div align="center"> <img src="pics/74dc31eb-6baa-47ea-ab1c-d27a0ca35093.png"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/74dc31eb-6baa-47ea-ab1c-d27a0ca35093.png"/> </div><br>
广度优先搜索一层一层遍历每一层得到的所有新节点要用队列存储起来以备下一层遍历的时候再遍历
@ -591,7 +591,7 @@ Backtracking回溯属于 DFS。
[Leetcode](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/) / [力扣](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/description/)
<div align="center"> <img src="pics/9823768c-212b-4b1a-b69a-b3f59e07b977.jpg"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9823768c-212b-4b1a-b69a-b3f59e07b977.jpg"/> </div><br>
```html
Input:Digit string "23"
@ -1194,7 +1194,7 @@ private boolean isPalindrome(String s, int begin, int end) {
[Leetcode](https://leetcode.com/problems/sudoku-solver/description/) / [力扣](https://leetcode-cn.com/problems/sudoku-solver/description/)
<div align="center"> <img src="pics/0e8fdc96-83c1-4798-9abe-45fc91d70b9d.png"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/0e8fdc96-83c1-4798-9abe-45fc91d70b9d.png"/> </div><br>
```java
private boolean[][] rowsUsed = new boolean[9][10];
@ -1253,7 +1253,7 @@ private int cubeNum(int i, int j) {
[Leetcode](https://leetcode.com/problems/n-queens/description/) / [力扣](https://leetcode-cn.com/problems/n-queens/description/)
<div align="center"> <img src="pics/067b310c-6877-40fe-9dcf-10654e737485.jpg"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/067b310c-6877-40fe-9dcf-10654e737485.jpg"/> </div><br>
n\*n 的矩阵中摆放 n 个皇后并且每个皇后不能在同一行同一列同一对角线上求所有的 n 皇后的解
@ -1261,12 +1261,12 @@ private int cubeNum(int i, int j) {
45 度对角线标记数组的长度为 2 \* n - 1通过下图可以明确 (r, c) 的位置所在的数组下标为 r + c
<div align="center"> <img src="pics/9c422923-1447-4a3b-a4e1-97e663738187.jpg" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9c422923-1447-4a3b-a4e1-97e663738187.jpg" width="300px"> </div><br>
135 度对角线标记数组的长度也是 2 \* n - 1(r, c) 的位置所在的数组下标为 n - 1 - (r - c)
<div align="center"> <img src="pics/7a85e285-e152-4116-b6dc-3fab27ba9437.jpg" width="300px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7a85e285-e152-4116-b6dc-3fab27ba9437.jpg" width="300px"> </div><br>
```java
private List<List<String>> solutions;
@ -1320,4 +1320,4 @@ private void backtracking(int row) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -537,4 +537,4 @@ public int maximumProduct(int[] nums) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -467,4 +467,4 @@ public int maxChunksToSorted(int[] arr) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -236,4 +236,4 @@ public int[] nextGreaterElements(int[] nums) {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -1045,7 +1045,7 @@ private void inOrder(TreeNode node, List<Integer> nums) {
# Trie
<div align="center"> <img src="pics/5c638d59-d4ae-4ba4-ad44-80bdc30f38dd.jpg"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/5c638d59-d4ae-4ba4-ad44-80bdc30f38dd.jpg"/> </div><br>
Trie又称前缀树或字典树用于判断字符串是否存在或者是否具有某种字符串前缀
@ -1186,4 +1186,4 @@ class MapSum {
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -37,4 +37,4 @@
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

View File

@ -37,4 +37,4 @@
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>

Some files were not shown because too many files have changed in this diff Show More