From 613c51bd45e836bcd40e0a1e2a6831321be38685 Mon Sep 17 00:00:00 2001
From: CyC2018 <1029579233@qq.com>
Date: Sun, 1 Apr 2018 20:17:38 +0800
Subject: [PATCH] auto commit
---
notes/Java 基础.md | 2 +-
notes/剑指 offer 题解.md | 53 ++++++++++++------
pics/41392d76-dd1d-4712-85d9-e8bb46b04a2d.png | Bin 0 -> 4096 bytes
3 files changed, 36 insertions(+), 19 deletions(-)
create mode 100644 pics/41392d76-dd1d-4712-85d9-e8bb46b04a2d.png
diff --git a/notes/Java 基础.md b/notes/Java 基础.md
index ba6cdd13..6cc8a936 100644
--- a/notes/Java 基础.md
+++ b/notes/Java 基础.md
@@ -535,7 +535,7 @@ Reflection is powerful, but should not be used indiscriminately. If it is possib
# 八、异常
-Throwable 可以用来表示任何可以作为异常抛出的类,分为两种: **Error** 和 **Exception**,其中 Error 用来表示编译时系统错误。
+Throwable 可以用来表示任何可以作为异常抛出的类,分为两种: **Error** 和 **Exception**,其中 Error 用来表示 JVM 无法处理的错误(比如 java.lang.OutOfMemoryError)。
Exception 分为两种:
diff --git a/notes/剑指 offer 题解.md b/notes/剑指 offer 题解.md
index 7292b327..b4781e57 100644
--- a/notes/剑指 offer 题解.md
+++ b/notes/剑指 offer 题解.md
@@ -797,13 +797,13 @@ private void printNumber(char[] number) {
① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,令该节点指向下下个节点,然后删除下一个节点,时间复杂度为 O(1)。
-
+
② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。
-综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个为节点以 O(n) 的时间复杂度操作节点的总次数。(2N-1)/N \~ 2,因此该算法的平均时间复杂度为 O(1)。
+综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数。(2N-1)/N \~ 2,因此该算法的平均时间复杂度为 O(1)。
```java
public ListNode deleteNode(ListNode head, ListNode tobeDelete) {
@@ -852,17 +852,17 @@ public ListNode deleteDuplication(ListNode pHead) {
## 解题思路
-应该注意到,'.' 是用来代替一个任意字符,而 '\*' 是用来重复前面的字符。这两个的作用不同,不能把 '.' 的作用和 '\*' 进行类比,从而把它当成重复前面字符一次。
+应该注意到,'.' 是用来当做一个任意字符,而 '\*' 是用来重复前面的字符。这两个的作用不同,不能把 '.' 的作用和 '\*' 进行类比,从而把它当成重复前面字符一次。
```html
p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1];
p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
p.charAt(j) == '*' :
- p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2] // in this case, a* only counts as empty
+ p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2] //a* only counts as empty
p.charAt(j-1) == s.charAt(i) or p.charAt(i-1) == '.':
- dp[i][j] = dp[i-1][j] // in this case, a* counts as multiple a
- or dp[i][j] = dp[i][j-1] // in this case, a* counts as single a
- or dp[i][j] = dp[i][j-2] // in this case, a* counts as empty
+ dp[i][j] = dp[i-1][j] // a* counts as multiple a
+ or dp[i][j] = dp[i][j-1] // a* counts as single a
+ or dp[i][j] = dp[i][j-2] // a* counts as empty
```
```java
@@ -1217,6 +1217,8 @@ public int min() {
## 解题思路
+使用一个栈来模拟压入弹出操作。
+
```java
public boolean IsPopOrder(int[] pushA, int[] popA) {
int n = pushA.length;
@@ -1494,7 +1496,7 @@ public class Solution {
public String Serialize(TreeNode root) {
if (root == null) return "#";
- return root.val + " " + Serialize(root.left) + " " + Serialize(root.right);
+ return root.val + " " + Serialize(root.left) + " " + Serialize(root.right);
}
public TreeNode Deserialize(String str) {
@@ -1557,7 +1559,7 @@ private void backtracking(char[] chars, boolean[] hasUsed, StringBuffer s) {
## 解题思路
-多数投票问题,可以利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题,使得时间复杂度为 O(n)。
+多数投票问题,可以利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题,使得时间复杂度为 O(N)。
使用 cnt 来统计一个元素出现的次数,当遍历到的元素和统计元素不相等时,令 cnt--。如果前面查找了 i 个元素,且 cnt == 0 ,说明前 i 个元素没有 majority,或者有 majority,但是出现的次数少于 i / 2 ,因为如果多于 i / 2 的话 cnt 就一定不会为 0 。此时剩下的 n - i 个元素中,majority 的数目依然多于 (n - i) / 2,因此继续查找就能找出 majority。
@@ -1978,7 +1980,7 @@ public int FirstNotRepeatingChar(String str) {
}
```
-以上的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么我们只需要统计的次数信息只有 0,1,更大,那么使用两个比特位就能存储这些信息。
+以上实现的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么我们只需要统计的次数信息只有 0,1,更大,那么使用两个比特位就能存储这些信息。
```java
public int FirstNotRepeatingChar(String str) {
@@ -2077,7 +2079,10 @@ Output:
## 解题思路
-可以用二分查找找出数字在数组的最左端和最右端。
+可以用二分查找找出数字在数组的最左端和最右端,找最左端和最右端在方法实现上的区别主要在于对 nums[m] == K 的处理:
+
+- 找最左端令 h = m - 1
+- 找最右端令 l = m + 1
```java
public int GetNumberOfK(int[] nums, int K) {
@@ -2313,7 +2318,7 @@ private void reverse(char[] c, int i, int j) {
## 解题思路
```java
-public String LeftRotateString(String str,int n) {
+public String LeftRotateString(String str, int n) {
if(str.length() == 0) return "";
char[] c = str.toCharArray();
reverse(c, 0, n - 1);
@@ -2365,7 +2370,7 @@ public ArrayList maxInWindows(int[] num, int size) {
### 动态规划解法
-空间复杂度:O(n2)
+空间复杂度:O(N2)
```java
private static int face = 6;
@@ -2393,7 +2398,7 @@ public double countProbability(int n, int s) {
### 动态规划解法 + 旋转数组
-空间复杂度:O(n)
+空间复杂度:O(N)
```java
private static int face = 6;
@@ -2449,11 +2454,11 @@ public boolean isContinuous(int[] nums) {
## 题目描述
-让小朋友们围成一个大圈。然后 , 他随机指定一个数 m, 让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌 , 然后可以在礼品箱中任意的挑选礼物 , 并且不再回到圈中 , 从他的下一个小朋友开始 , 继续 0...m-1 报数 .... 这样下去 .... 直到剩下最后一个小朋友 , 可以不用表演。
+让小朋友们围成一个大圈。然后,他随机指定一个数 m,让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续 0...m-1 报数 .... 这样下去 .... 直到剩下最后一个小朋友,可以不用表演。
## 解题思路
-约瑟夫环
+约瑟夫环,圆圈长度为 n 的解可以看成长度为 n-1 的解再加上报数的长度 m。因为是圆圈,所以最后需要对 n 取余。
```java
public int LastRemaining_Solution(int n, int m) {
@@ -2471,6 +2476,8 @@ public int LastRemaining_Solution(int n, int m) {
## 解题思路
+使用贪心策略,假设第 i 轮进行卖出操作,买入操作价格应该是 i 之前并且价格最低。
+
```java
public int maxProfit(int[] prices) {
int n = prices.length;
@@ -2503,7 +2510,11 @@ public int Sum_Solution(int n) {
# 65. 不用加减乘除做加法
-a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。
+## 解题思路
+
+a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。
+
+递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。
```java
public int Add(int num1, int num2) {
@@ -2536,6 +2547,8 @@ public int[] multiply(int[] A) {
# 67. 把字符串转换成整数
+## 解题思路
+
```java
public int StrToInt(String str) {
if (str.length() == 0) return 0;
@@ -2544,7 +2557,7 @@ public int StrToInt(String str) {
int ret = 0;
for (int i = 0; i < chars.length; i++) {
if (i == 0 && (chars[i] == '+' || chars[i] == '-')) continue;
- if (chars[i] < '0' || chars[i] > '9') return 0;
+ if (chars[i] < '0' || chars[i] > '9') return 0; // 非法输入
ret = ret * 10 + (chars[i] - '0');
}
return isNegative ? -ret : ret;
@@ -2559,6 +2572,8 @@ public int StrToInt(String str) {
+二叉查找树中,两个节点 p, q 的公共祖先 root 满足 p.val <= root.val && root.val <= q.val,只要找到满足这个条件的最低层节点即可。换句话说,应该先考虑子树的解而不是根节点的解,二叉树的后序遍历操作满足这个特性。在本题中我们可以利用后序遍历的特性,先在左右子树中查找解,最后再考虑根节点的解。
+
```java
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q);
@@ -2571,6 +2586,8 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+在左右子树中查找两个节点的最低公共祖先,如果在其中一颗子树中查找到,那么就返回这个解,否则可以认为根节点就是最低公共祖先。
+
```java
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
diff --git a/pics/41392d76-dd1d-4712-85d9-e8bb46b04a2d.png b/pics/41392d76-dd1d-4712-85d9-e8bb46b04a2d.png
new file mode 100644
index 0000000000000000000000000000000000000000..d2fd2c630bbb7c7c1a464920250cadf625f57e93
GIT binary patch
literal 4096
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
literal 0
HcmV?d00001