diff --git a/README.md b/README.md index ded19a67..116e2a4b 100644 --- a/README.md +++ b/README.md @@ -208,25 +208,28 @@ Power by [logomakr](https://logomakr.com/). 感谢以下人员对本仓库做出的贡献,当然不仅仅只有这些贡献者,这里就不一一列举了。如果你希望被添加到这个名单中,并且提交过 Issue 或者 PR,请与笔者联系。 - + - + - + - + - + - + - + + + + #### License diff --git a/notes/Java 容器.md b/notes/Java 容器.md index 84189928..e42a42f0 100644 --- a/notes/Java 容器.md +++ b/notes/Java 容器.md @@ -738,7 +738,7 @@ HashMap 构造函数允许用户传入的容量不是 2 的 n 次方,因为它 ``` mask |= mask >> 1 11011000 -mask |= mask >> 2 11111100 +mask |= mask >> 2 11111110 mask |= mask >> 4 11111111 ``` diff --git a/notes/Leetcode 题解.md b/notes/Leetcode 题解.md index 04a751c7..e128e1d3 100644 --- a/notes/Leetcode 题解.md +++ b/notes/Leetcode 题解.md @@ -2415,27 +2415,19 @@ public int climbStairs(int n) { 定义 dp 数组用来存储最大的抢劫量,其中 dp[i] 表示抢到第 i 个住户时的最大抢劫量。 由于不能抢劫邻近住户,因此如果抢劫了第 i 个住户那么只能抢劫 i - 2 或者 i - 3 的住户,所以 - -

+dp[i] = max(dp[i-1], dp[i-2] + nums[i])
```java public int rob(int[] nums) { - int n = nums.length; - if (n == 0) { - return 0; - } - if (n == 1) { - return nums[0]; - } - int pre3 = 0, pre2 = 0, pre1 = 0; - for (int i = 0; i < n; i++) { - int cur = Math.max(pre2, pre3) + nums[i]; - pre3 = pre2; + int pre2 = 0, pre1 = 0; + for (int i = 0; i < nums.length; i++) { + int cur = Math.max(pre2 + nums[i], pre1); pre2 = pre1; pre1 = cur; } - return Math.max(pre1, pre2); + return pre1; } + ``` **强盗在环形街区抢劫** @@ -2443,7 +2435,7 @@ public int rob(int[] nums) { [213. House Robber II (Medium)](https://leetcode.com/problems/house-robber-ii/description/) ```java -public int rob(int[] nums) { +public int rob(int[] nums) { if (nums == null || nums.length == 0) { return 0; } @@ -2454,15 +2446,14 @@ public int rob(int[] nums) { return Math.max(rob(nums, 0, n - 2), rob(nums, 1, n - 1)); } -private int rob(int[] nums, int first, int last) { - int pre3 = 0, pre2 = 0, pre1 = 0; +private int rob(int[] nums, int first, int last) { + int pre2 = 0, pre1 = 0; for (int i = first; i <= last; i++) { - int cur = Math.max(pre3, pre2) + nums[i]; - pre3 = pre2; + int cur = Math.max(pre1, pre2 + nums[i]); pre2 = pre1; pre1 = cur; } - return Math.max(pre2, pre1); + return pre1; } ``` @@ -2514,9 +2505,9 @@ public int minPathSum(int[][] grid) { for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i == 0) { - dp[j] = dp[j - 1]; + if (j>0) dp[j] = dp[j - 1]; } else { - dp[j] = Math.min(dp[j - 1], dp[j]); + if (j>0) dp[j] = Math.min(dp[j - 1], dp[j]); } dp[j] += grid[i][j]; } @@ -7063,4 +7054,3 @@ public int[] countBits(int num) { - 何海涛, 软件工程师. 剑指 Offer: 名企面试官精讲典型编程题[M]. 电子工业出版社, 2014. - 《编程之美》小组. 编程之美[M]. 电子工业出版社, 2008. - 左程云. 程序员代码面试指南[M]. 电子工业出版社, 2015. - diff --git a/notes/MySQL.md b/notes/MySQL.md index 2c5d8935..f5479685 100644 --- a/notes/MySQL.md +++ b/notes/MySQL.md @@ -374,7 +374,7 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 ### 2. 连接 -可以将原来的连接分解成多个单表连接查询,然后在用户程序中进行连接。 +可以将原来的连接分解成多个单表查询,然后在用户程序中进行连接。 ### 3. ID 唯一性 diff --git a/notes/分布式.md b/notes/分布式.md index a39ae35e..d2b2f974 100644 --- a/notes/分布式.md +++ b/notes/分布式.md @@ -99,7 +99,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点的父 # 二、分布式事务 -指事务的操作位于不同的节点上,需要保证事务的 AICD 特性。 +指事务的操作位于不同的节点上,需要保证事务的 ACID 特性。 例如在下单场景下,库存和订单如果不在同一个节点上,就涉及分布式事务。 @@ -335,4 +335,5 @@ Raft 也是分布式一致性协议,主要是用来竞选主节点。 - [What is CAP theorem in distributed database system?](http://www.colooshiki.com/index.php/2017/04/20/what-is-cap-theorem-in-distributed-database-system/) - [NEAT ALGORITHMS - PAXOS](http://harry.me/blog/2014/12/27/neat-algorithms-paxos/) - [Paxos By Example](https://angus.nyc/2012/paxos-by-example/) +- [ACID](https://en.wikipedia.org/wiki/ACID_(computer_science)) diff --git a/notes/算法.md b/notes/算法.md index cb83830b..1bc0690a 100644 --- a/notes/算法.md +++ b/notes/算法.md @@ -459,7 +459,7 @@ public abstract class MergeSort> extends Sort { 将一个大数组分成两个小数组去求解。 -因为每次都将问题对半分成两个子问题,而这种对半分的算法复杂度一般为 O(NlogN),因此该归并排序方法的时间复杂度也为 O(NlogN)。 +因为每次都将问题对半分成两个子问题,这种对半分的算法复杂度一般为 O(NlogN)。 ```java public class Up2DownMergeSort> extends MergeSort { @@ -617,7 +617,7 @@ public class ThreeWayQuickSort> extends QuickSort { 可以利用这个特性找出数组的第 k 个元素。 -该算法是线性级别的,因为每次能将数组二分,那么比较的总次数为 (N+N/2+N/4+..),直到找到第 k 个元素,这个和显然小于 2N。 +该算法是线性级别的,假设每次能将数组二分,那么比较的总次数为 (N+N/2+N/4+..),直到找到第 k 个元素,这个和显然小于 2N。 ```java public T select(T[] nums, int k) { @@ -2292,7 +2292,7 @@ from H1 to H3 可以将每种字符转换成二进制编码,例如将 a 转换为 00,b 转换为 01,c 转换为 10,d 转换为 11。这是最简单的一种编码方式,没有考虑各个字符的权值(出现频率)。而哈夫曼编码采用了贪心策略,使出现频率最高的字符的编码最短,从而保证整体的编码长度最短。 -首先生成一颗哈夫曼树,每次生成过程中选取频率最少的两个节点,生成一个新节点作为它们的父节点,并且新节点的频率为两个节点的和。选取频率最少的原因是,生成过程使得先选取的节点在树的最底层,那么需要的编码长度更长,频率更少可以使得总编码长度更少。 +首先生成一颗哈夫曼树,每次生成过程中选取频率最少的两个节点,生成一个新节点作为它们的父节点,并且新节点的频率为两个节点的和。选取频率最少的原因是,生成过程使得先选取的节点位于树的更低层,那么需要的编码长度更长,频率更少可以使得总编码长度更少。 生成编码时,从根节点出发,向左遍历则添加二进制位 0,向右则添加二进制位 1,直到遍历到叶子节点,叶子节点代表的字符的编码就是这个路径编码。 diff --git a/notes/系统设计基础.md b/notes/系统设计基础.md index 4a961140..ffa5de70 100644 --- a/notes/系统设计基础.md +++ b/notes/系统设计基础.md @@ -4,6 +4,7 @@ * [三、扩展性](#三扩展性) * [四、可用性](#四可用性) * [五、安全性](#五安全性) +* [参考资料](#参考资料) @@ -102,3 +103,7 @@ # 五、安全性 要求系统的应对各种攻击手段时能够有可靠的应对措施。 + +# 参考资料 + +- 大型网站技术架构:核心原理与案例分析