Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wushizhenking
CS-Notes
提交
613c51bd
C
CS-Notes
项目概览
wushizhenking
/
CS-Notes
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
CS-Notes
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
613c51bd
编写于
4月 01, 2018
作者:
C
CyC2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
auto commit
上级
aa2e48cb
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
36 addition
and
19 deletion
+36
-19
notes/Java 基础.md
notes/Java 基础.md
+1
-1
notes/剑指 offer 题解.md
notes/剑指 offer 题解.md
+35
-18
pics/41392d76-dd1d-4712-85d9-e8bb46b04a2d.png
pics/41392d76-dd1d-4712-85d9-e8bb46b04a2d.png
+0
-0
未找到文件。
notes/Java 基础.md
浏览文件 @
613c51bd
...
@@ -535,7 +535,7 @@ Reflection is powerful, but should not be used indiscriminately. If it is possib
...
@@ -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 分为两种:
Exception 分为两种:
...
...
notes/剑指 offer 题解.md
浏览文件 @
613c51bd
...
@@ -797,13 +797,13 @@ private void printNumber(char[] number) {
...
@@ -797,13 +797,13 @@ private void printNumber(char[] number) {
① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,令该节点指向下下个节点,然后删除下一个节点,时间复杂度为 O(1)。
① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,令该节点指向下下个节点,然后删除下一个节点,时间复杂度为 O(1)。
<div
align=
"center"
>
<img
src=
"../pics//
004edd56-1546-4052-a7f9-a9f7895ccec5
.png"
width=
"600"
/>
</div><br>
<div
align=
"center"
>
<img
src=
"../pics//
41392d76-dd1d-4712-85d9-e8bb46b04a2d
.png"
width=
"600"
/>
</div><br>
② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。
② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。
<div
align=
"center"
>
<img
src=
"../pics//db4921d4-184b-48ba-a3cf-1d1141e3ba2d.png"
width=
"600"
/>
</div><br>
<div
align=
"center"
>
<img
src=
"../pics//db4921d4-184b-48ba-a3cf-1d1141e3ba2d.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)。
综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个
尾节点以 O(N
) 的时间复杂度操作节点的总次数。(2N-1)/N
\~
2,因此该算法的平均时间复杂度为 O(1)。
```
java
```
java
public
ListNode
deleteNode
(
ListNode
head
,
ListNode
tobeDelete
)
{
public
ListNode
deleteNode
(
ListNode
head
,
ListNode
tobeDelete
)
{
...
@@ -852,17 +852,17 @@ public ListNode deleteDuplication(ListNode pHead) {
...
@@ -852,17 +852,17 @@ public ListNode deleteDuplication(ListNode pHead) {
## 解题思路
## 解题思路
应该注意到,'.' 是用来
代替
一个任意字符,而 '
\*
' 是用来重复前面的字符。这两个的作用不同,不能把 '.' 的作用和 '
\*
' 进行类比,从而把它当成重复前面字符一次。
应该注意到,'.' 是用来
当做
一个任意字符,而 '
\*
' 是用来重复前面的字符。这两个的作用不同,不能把 '.' 的作用和 '
\*
' 进行类比,从而把它当成重复前面字符一次。
```
html
```
html
p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1];
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) == '.' : dp[i][j] = dp[i-1][j-1];
p.charAt(j) == '*' :
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) == '.':
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
dp[i][j] = dp[i-1][j] // 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-1] // a* counts as single a
or dp[i][j] = dp[i][j-2] //
in this case,
a* counts as empty
or dp[i][j] = dp[i][j-2] // a* counts as empty
```
```
```
java
```
java
...
@@ -1217,6 +1217,8 @@ public int min() {
...
@@ -1217,6 +1217,8 @@ public int min() {
## 解题思路
## 解题思路
使用一个栈来模拟压入弹出操作。
```
java
```
java
public
boolean
IsPopOrder
(
int
[]
pushA
,
int
[]
popA
)
{
public
boolean
IsPopOrder
(
int
[]
pushA
,
int
[]
popA
)
{
int
n
=
pushA
.
length
;
int
n
=
pushA
.
length
;
...
@@ -1494,7 +1496,7 @@ public class Solution {
...
@@ -1494,7 +1496,7 @@ public class Solution {
public
String
Serialize
(
TreeNode
root
)
{
public
String
Serialize
(
TreeNode
root
)
{
if
(
root
==
null
)
return
"#"
;
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
)
{
public
TreeNode
Deserialize
(
String
str
)
{
...
@@ -1557,7 +1559,7 @@ private void backtracking(char[] chars, boolean[] hasUsed, StringBuffer s) {
...
@@ -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。
使用 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) {
...
@@ -1978,7 +1980,7 @@ public int FirstNotRepeatingChar(String str) {
}
}
```
```
以上的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么我们只需要统计的次数信息只有 0,1,更大,那么使用两个比特位就能存储这些信息。
以上
实现
的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么我们只需要统计的次数信息只有 0,1,更大,那么使用两个比特位就能存储这些信息。
```
java
```
java
public
int
FirstNotRepeatingChar
(
String
str
)
{
public
int
FirstNotRepeatingChar
(
String
str
)
{
...
@@ -2077,7 +2079,10 @@ Output:
...
@@ -2077,7 +2079,10 @@ Output:
## 解题思路
## 解题思路
可以用二分查找找出数字在数组的最左端和最右端。
可以用二分查找找出数字在数组的最左端和最右端,找最左端和最右端在方法实现上的区别主要在于对 nums[m] == K 的处理:
-
找最左端令 h = m - 1
-
找最右端令 l = m + 1
```
java
```
java
public
int
GetNumberOfK
(
int
[]
nums
,
int
K
)
{
public
int
GetNumberOfK
(
int
[]
nums
,
int
K
)
{
...
@@ -2313,7 +2318,7 @@ private void reverse(char[] c, int i, int j) {
...
@@ -2313,7 +2318,7 @@ private void reverse(char[] c, int i, int j) {
## 解题思路
## 解题思路
```
java
```
java
public
String
LeftRotateString
(
String
str
,
int
n
)
{
public
String
LeftRotateString
(
String
str
,
int
n
)
{
if
(
str
.
length
()
==
0
)
return
""
;
if
(
str
.
length
()
==
0
)
return
""
;
char
[]
c
=
str
.
toCharArray
();
char
[]
c
=
str
.
toCharArray
();
reverse
(
c
,
0
,
n
-
1
);
reverse
(
c
,
0
,
n
-
1
);
...
@@ -2365,7 +2370,7 @@ public ArrayList<Integer> maxInWindows(int[] num, int size) {
...
@@ -2365,7 +2370,7 @@ public ArrayList<Integer> maxInWindows(int[] num, int size) {
### 动态规划解法
### 动态规划解法
空间复杂度:O(
n
<sup>
2
</sup>
)
空间复杂度:O(
N
<sup>
2
</sup>
)
```
java
```
java
private
static
int
face
=
6
;
private
static
int
face
=
6
;
...
@@ -2393,7 +2398,7 @@ public double countProbability(int n, int s) {
...
@@ -2393,7 +2398,7 @@ public double countProbability(int n, int s) {
### 动态规划解法 + 旋转数组
### 动态规划解法 + 旋转数组
空间复杂度:O(
n
)
空间复杂度:O(
N
)
```
java
```
java
private
static
int
face
=
6
;
private
static
int
face
=
6
;
...
@@ -2449,11 +2454,11 @@ public boolean isContinuous(int[] nums) {
...
@@ -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
```
java
public
int
LastRemaining_Solution
(
int
n
,
int
m
)
{
public
int
LastRemaining_Solution
(
int
n
,
int
m
)
{
...
@@ -2471,6 +2476,8 @@ public int LastRemaining_Solution(int n, int m) {
...
@@ -2471,6 +2476,8 @@ public int LastRemaining_Solution(int n, int m) {
## 解题思路
## 解题思路
使用贪心策略,假设第 i 轮进行卖出操作,买入操作价格应该是 i 之前并且价格最低。
```
java
```
java
public
int
maxProfit
(
int
[]
prices
)
{
public
int
maxProfit
(
int
[]
prices
)
{
int
n
=
prices
.
length
;
int
n
=
prices
.
length
;
...
@@ -2503,7 +2510,11 @@ public int Sum_Solution(int n) {
...
@@ -2503,7 +2510,11 @@ public int Sum_Solution(int n) {
# 65. 不用加减乘除做加法
# 65. 不用加减乘除做加法
a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。
## 解题思路
a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。
递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。
```
java
```
java
public
int
Add
(
int
num1
,
int
num2
)
{
public
int
Add
(
int
num1
,
int
num2
)
{
...
@@ -2536,6 +2547,8 @@ public int[] multiply(int[] A) {
...
@@ -2536,6 +2547,8 @@ public int[] multiply(int[] A) {
# 67. 把字符串转换成整数
# 67. 把字符串转换成整数
## 解题思路
```
java
```
java
public
int
StrToInt
(
String
str
)
{
public
int
StrToInt
(
String
str
)
{
if
(
str
.
length
()
==
0
)
return
0
;
if
(
str
.
length
()
==
0
)
return
0
;
...
@@ -2544,7 +2557,7 @@ public int StrToInt(String str) {
...
@@ -2544,7 +2557,7 @@ public int StrToInt(String str) {
int
ret
=
0
;
int
ret
=
0
;
for
(
int
i
=
0
;
i
<
chars
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
chars
.
length
;
i
++)
{
if
(
i
==
0
&&
(
chars
[
i
]
==
'+'
||
chars
[
i
]
==
'-'
))
continue
;
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'
);
ret
=
ret
*
10
+
(
chars
[
i
]
-
'0'
);
}
}
return
isNegative
?
-
ret
:
ret
;
return
isNegative
?
-
ret
:
ret
;
...
@@ -2559,6 +2572,8 @@ public int StrToInt(String str) {
...
@@ -2559,6 +2572,8 @@ public int StrToInt(String str) {
<div
align=
"center"
>
<img
src=
"../pics//293d2af9-de1d-403e-bed0-85d029383528.png"
width=
"300"
/>
</div><br>
<div
align=
"center"
>
<img
src=
"../pics//293d2af9-de1d-403e-bed0-85d029383528.png"
width=
"300"
/>
</div><br>
二叉查找树中,两个节点 p, q 的公共祖先 root 满足 p.val <= root.val && root.val <= q.val,只要找到满足这个条件的最低层节点即可。换句话说,应该先考虑子树的解而不是根节点的解,二叉树的后序遍历操作满足这个特性。在本题中我们可以利用后序遍历的特性,先在左右子树中查找解,最后再考虑根节点的解。
```
java
```
java
public
TreeNode
lowestCommonAncestor
(
TreeNode
root
,
TreeNode
p
,
TreeNode
q
)
{
public
TreeNode
lowestCommonAncestor
(
TreeNode
root
,
TreeNode
p
,
TreeNode
q
)
{
if
(
root
.
val
>
p
.
val
&&
root
.
val
>
q
.
val
)
return
lowestCommonAncestor
(
root
.
left
,
p
,
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) {
...
@@ -2571,6 +2586,8 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
<div
align=
"center"
>
<img
src=
"../pics//37a72755-4890-4b42-9eab-b0084e0c54d9.png"
width=
"300"
/>
</div><br>
<div
align=
"center"
>
<img
src=
"../pics//37a72755-4890-4b42-9eab-b0084e0c54d9.png"
width=
"300"
/>
</div><br>
在左右子树中查找两个节点的最低公共祖先,如果在其中一颗子树中查找到,那么就返回这个解,否则可以认为根节点就是最低公共祖先。
```
java
```
java
public
TreeNode
lowestCommonAncestor
(
TreeNode
root
,
TreeNode
p
,
TreeNode
q
)
{
public
TreeNode
lowestCommonAncestor
(
TreeNode
root
,
TreeNode
p
,
TreeNode
q
)
{
if
(
root
==
null
||
root
==
p
||
root
==
q
)
return
root
;
if
(
root
==
null
||
root
==
p
||
root
==
q
)
return
root
;
...
...
pics/41392d76-dd1d-4712-85d9-e8bb46b04a2d.png
0 → 100644
浏览文件 @
613c51bd
4.0 KB
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录