Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wushizhenking
CS-Notes
提交
ea236194
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,发现更多精彩内容 >>
提交
ea236194
编写于
6月 28, 2018
作者:
C
CyC2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
auto commit
上级
095ae3ae
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
82 addition
and
64 deletion
+82
-64
notes/剑指 offer 题解.md
notes/剑指 offer 题解.md
+82
-64
未找到文件。
notes/剑指 offer 题解.md
浏览文件 @
ea236194
...
...
@@ -2025,7 +2025,8 @@ private int beginNumber(int digit) {
可以看成是一个排序问题,在比较两个字符串 S1 和 S2 的大小时,应该比较的是 S1+S2 和 S2+S1 的大小,如果 S1+S2 < S2+S1,那么应该把 S1 排在前面,否则应该把 S2 排在前面。
```
java
public
String
PrintMinNumber
(
int
[]
numbers
)
{
public
String
PrintMinNumber
(
int
[]
numbers
)
{
if
(
numbers
==
null
||
numbers
.
length
==
0
)
return
""
;
int
n
=
numbers
.
length
;
...
...
@@ -2051,7 +2052,8 @@ public String PrintMinNumber(int[] numbers) {
## 解题思路
```
java
public
int
numDecodings
(
String
s
)
{
public
int
numDecodings
(
String
s
)
{
if
(
s
==
null
||
s
.
length
()
==
0
)
return
0
;
int
n
=
s
.
length
();
...
...
@@ -2094,15 +2096,16 @@ public int numDecodings(String s) {
应该用动态规划求解,而不是深度优先搜索,深度优先搜索过于复杂,不是最优解。
```
java
public
int
getMost
(
int
[][]
values
)
{
public
int
getMost
(
int
[][]
values
)
{
if
(
values
==
null
||
values
.
length
==
0
||
values
[
0
].
length
==
0
)
return
0
;
int
m
=
values
.
length
,
n
=
values
[
0
].
length
;
int
n
=
values
[
0
].
length
;
int
[]
dp
=
new
int
[
n
];
for
(
int
i
=
0
;
i
<
m
;
i
++
)
{
dp
[
0
]
+=
value
s
[
i
]
[
0
];
for
(
int
j
=
1
;
j
<
n
;
j
++)
dp
[
j
]
=
Math
.
max
(
dp
[
j
],
dp
[
j
-
1
])
+
values
[
i
][
j
];
for
(
int
[]
value
:
values
)
{
dp
[
0
]
+=
value
[
0
];
for
(
int
i
=
1
;
i
<
n
;
i
++)
dp
[
i
]
=
Math
.
max
(
dp
[
i
],
dp
[
i
-
1
])
+
value
[
i
];
}
return
dp
[
n
-
1
];
}
...
...
@@ -2117,21 +2120,22 @@ public int getMost(int[][] values) {
## 解题思路
```
java
public
int
longestSubStringWithoutDuplication
(
String
str
)
{
public
int
longestSubStringWithoutDuplication
(
String
str
)
{
int
curLen
=
0
;
int
maxLen
=
0
;
int
[]
preIndexs
=
new
int
[
26
];
Arrays
.
fill
(
preIndexs
,
-
1
);
for
(
int
i
=
0
;
i
<
str
.
length
();
i
++)
{
int
c
=
str
.
charAt
(
i
)
-
'a'
;
int
preI
ndex
=
preIndexs
[
c
];
if
(
preI
ndex
==
-
1
||
i
-
preIndex
>
curLen
)
{
for
(
int
curI
=
0
;
curI
<
str
.
length
();
curI
++)
{
int
c
=
str
.
charAt
(
curI
)
-
'a'
;
int
preI
=
preIndexs
[
c
];
if
(
preI
==
-
1
||
curI
-
preI
>
curLen
)
{
curLen
++;
}
else
{
maxLen
=
Math
.
max
(
maxLen
,
curLen
);
curLen
=
i
-
preIndex
;
curLen
=
curI
-
preI
;
}
preIndexs
[
c
]
=
i
;
preIndexs
[
c
]
=
curI
;
}
maxLen
=
Math
.
max
(
maxLen
,
curLen
);
return
maxLen
;
...
...
@@ -2144,28 +2148,29 @@ public int longestSubStringWithoutDuplication(String str) {
## 题目描述
把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,但 14 不是,因为它包含因子 7。
习惯上我们把 1 当做是第一个丑数。求按从小到大的顺序的第 N 个丑数。
把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。求按从小到大的顺序的第 N 个丑数。
## 解题思路
```
java
public
int
GetUglyNumber_Solution
(
int
index
)
{
if
(
index
<=
6
)
return
index
;
public
int
GetUglyNumber_Solution
(
int
N
)
{
if
(
N
<=
6
)
return
N
;
int
i2
=
0
,
i3
=
0
,
i5
=
0
;
int
[]
dp
=
new
int
[
index
];
int
[]
dp
=
new
int
[
N
];
dp
[
0
]
=
1
;
for
(
int
i
=
1
;
i
<
index
;
i
++)
{
int
n
2
=
dp
[
i2
]
*
2
,
n3
=
dp
[
i3
]
*
3
,
n
5
=
dp
[
i5
]
*
5
;
dp
[
i
]
=
Math
.
min
(
n
2
,
Math
.
min
(
n3
,
n
5
));
if
(
dp
[
i
]
==
n2
)
for
(
int
i
=
1
;
i
<
N
;
i
++)
{
int
n
ext2
=
dp
[
i2
]
*
2
,
next3
=
dp
[
i3
]
*
3
,
next
5
=
dp
[
i5
]
*
5
;
dp
[
i
]
=
Math
.
min
(
n
ext2
,
Math
.
min
(
next3
,
next
5
));
if
(
dp
[
i
]
==
n
ext
2
)
i2
++;
if
(
dp
[
i
]
==
n3
)
if
(
dp
[
i
]
==
n
ext
3
)
i3
++;
if
(
dp
[
i
]
==
n5
)
if
(
dp
[
i
]
==
n
ext
5
)
i5
++;
}
return
dp
[
index
-
1
];
return
dp
[
N
-
1
];
}
```
...
...
@@ -2182,7 +2187,8 @@ public int GetUglyNumber_Solution(int index) {
最直观的解法是使用 HashMap 对出现次数进行统计,但是考虑到要统计的字符范围有限,因此可以使用整型数组代替 HashMap。
```
java
public
int
FirstNotRepeatingChar
(
String
str
)
{
public
int
FirstNotRepeatingChar
(
String
str
)
{
int
[]
cnts
=
new
int
[
256
];
for
(
int
i
=
0
;
i
<
str
.
length
();
i
++)
cnts
[
str
.
charAt
(
i
)]++;
...
...
@@ -2196,18 +2202,19 @@ public int FirstNotRepeatingChar(String str) {
以上实现的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么我们只需要统计的次数信息只有 0,1,更大,使用两个比特位就能存储这些信息。
```
java
public
int
FirstNotRepeatingChar
(
String
str
)
{
public
int
FirstNotRepeatingChar2
(
String
str
)
{
BitSet
bs1
=
new
BitSet
(
256
);
BitSet
bs2
=
new
BitSet
(
256
);
for
(
char
c
:
str
.
toCharArray
())
{
if
(!
bs1
.
get
(
c
)
&&
!
bs2
.
get
(
c
))
bs1
.
set
(
c
);
// 0 0
bs1
.
set
(
c
);
// 0 0
-> 0 1
else
if
(
bs1
.
get
(
c
)
&&
!
bs2
.
get
(
c
))
bs2
.
set
(
c
);
// 0 1
bs2
.
set
(
c
);
// 0 1
-> 1 1
}
for
(
int
i
=
0
;
i
<
str
.
length
();
i
++)
{
char
c
=
str
.
charAt
(
i
);
if
(
bs1
.
get
(
c
)
&&
!
bs2
.
get
(
c
))
if
(
bs1
.
get
(
c
)
&&
!
bs2
.
get
(
c
))
// 0 1
return
i
;
}
return
-
1
;
...
...
@@ -2226,15 +2233,17 @@ public int FirstNotRepeatingChar(String str) {
```
java
private
long
cnt
=
0
;
private
int
[]
tmp
;
// 在这里创建辅助数组,而不是在 merge() 递归函数中创建
private
int
[]
tmp
;
// 在这里创建辅助数组,而不是在 merge() 递归函数中创建
public
int
InversePairs
(
int
[]
nums
)
{
public
int
InversePairs
(
int
[]
nums
)
{
tmp
=
new
int
[
nums
.
length
];
mergeSort
(
nums
,
0
,
nums
.
length
-
1
);
return
(
int
)
(
cnt
%
1000000007
);
}
private
void
mergeSort
(
int
[]
nums
,
int
l
,
int
h
)
{
private
void
mergeSort
(
int
[]
nums
,
int
l
,
int
h
)
{
if
(
h
-
l
<
1
)
return
;
int
m
=
l
+
(
h
-
l
)
/
2
;
...
...
@@ -2243,7 +2252,8 @@ private void mergeSort(int[] nums, int l, int h) {
merge
(
nums
,
l
,
m
,
h
);
}
private
void
merge
(
int
[]
nums
,
int
l
,
int
m
,
int
h
)
{
private
void
merge
(
int
[]
nums
,
int
l
,
int
m
,
int
h
)
{
int
i
=
l
,
j
=
m
+
1
,
k
=
l
;
while
(
i
<=
m
||
j
<=
h
)
{
if
(
i
>
m
)
...
...
@@ -2254,7 +2264,7 @@ private void merge(int[] nums, int l, int m, int h) {
tmp
[
k
]
=
nums
[
i
++];
else
{
tmp
[
k
]
=
nums
[
j
++];
this
.
cnt
+=
m
-
i
+
1
;
// a[i] > a[j],说明 a[i...mid] 都大于 a
[j]
this
.
cnt
+=
m
-
i
+
1
;
// nums[i] >= nums[j],说明 nums[i...mid] 都大于 nums
[j]
}
k
++;
}
...
...
@@ -2278,7 +2288,8 @@ private void merge(int[] nums, int l, int m, int h) {
当访问 A 链表的指针访问到链表尾部时,令它从链表 B 的头部重新开始访问链表 B;同样地,当访问 B 链表的指针访问到链表尾部时,令它从链表 A 的头部重新开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。
```
java
public
ListNode
FindFirstCommonNode
(
ListNode
pHead1
,
ListNode
pHead2
)
{
public
ListNode
FindFirstCommonNode
(
ListNode
pHead1
,
ListNode
pHead2
)
{
ListNode
l1
=
pHead1
,
l2
=
pHead2
;
while
(
l1
!=
l2
)
{
l1
=
(
l1
==
null
)
?
pHead2
:
l1
.
next
;
...
...
@@ -2305,13 +2316,15 @@ Output:
## 解题思路
```
java
public
int
GetNumberOfK
(
int
[]
nums
,
int
K
)
{
public
int
GetNumberOfK
(
int
[]
nums
,
int
K
)
{
int
first
=
binarySearch
(
nums
,
K
);
int
last
=
binarySearch
(
nums
,
K
+
1
);
return
(
first
==
nums
.
length
||
nums
[
first
]
!=
K
)
?
0
:
last
-
first
;
}
private
int
binarySearch
(
int
[]
nums
,
int
K
)
{
private
int
binarySearch
(
int
[]
nums
,
int
K
)
{
int
l
=
0
,
h
=
nums
.
length
;
while
(
l
<
h
)
{
int
m
=
l
+
(
h
-
l
)
/
2
;
...
...
@@ -2336,12 +2349,14 @@ private int binarySearch(int[] nums, int K) {
private
TreeNode
ret
;
private
int
cnt
=
0
;
public
TreeNode
KthNode
(
TreeNode
pRoot
,
int
k
)
{
public
TreeNode
KthNode
(
TreeNode
pRoot
,
int
k
)
{
inOrder
(
pRoot
,
k
);
return
ret
;
}
private
void
inOrder
(
TreeNode
root
,
int
k
)
{
private
void
inOrder
(
TreeNode
root
,
int
k
)
{
if
(
root
==
null
||
cnt
>=
k
)
return
;
inOrder
(
root
.
left
,
k
);
...
...
@@ -2365,7 +2380,8 @@ private void inOrder(TreeNode root, int k) {
## 解题思路
```
java
public
int
TreeDepth
(
TreeNode
root
)
{
public
int
TreeDepth
(
TreeNode
root
)
{
return
root
==
null
?
0
:
1
+
Math
.
max
(
TreeDepth
(
root
.
left
),
TreeDepth
(
root
.
right
));
}
```
...
...
@@ -2385,13 +2401,15 @@ public int TreeDepth(TreeNode root) {
```
java
private
boolean
isBalanced
=
true
;
public
boolean
IsBalanced_Solution
(
TreeNode
root
)
{
public
boolean
IsBalanced_Solution
(
TreeNode
root
)
{
height
(
root
);
return
isBalanced
;
}
private
int
height
(
TreeNode
root
)
{
if
(
root
==
null
)
private
int
height
(
TreeNode
root
)
{
if
(
root
==
null
||
!
isBalanced
)
return
0
;
int
left
=
height
(
root
.
left
);
int
right
=
height
(
root
.
right
);
...
...
@@ -2411,26 +2429,24 @@ private int height(TreeNode root) {
## 解题思路
两个不相等的元素在位级表示上必定会有一位存在不同。
将数组的所有元素异或得到的结果为不存在重复的两个元素异或的结果。
两个不相等的元素在位级表示上必定会有一位存在不同,将数组的所有元素异或得到的结果为不存在重复的两个元素异或的结果。
diff &= -diff 得到出 diff 最右侧不为 0 的位,也就是不存在重复的两个元素在位级表示上最右侧不同的那一位,利用这一位就可以将两个元素区分开来。
```
java
public
void
FindNumsAppearOnce
(
int
[]
nums
,
int
num1
[],
int
num2
[])
{
int
diff
=
0
;
for
(
int
num
:
nums
)
diff
^=
num
;
// 得到最右一位
diff
&=
-
diff
;
for
(
int
num
:
nums
)
{
if
((
num
&
diff
)
==
0
)
num1
[
0
]
^=
num
;
else
num2
[
0
]
^=
num
;
}
public
void
FindNumsAppearOnce
(
int
[]
nums
,
int
num1
[],
int
num2
[])
{
int
diff
=
0
;
for
(
int
num
:
nums
)
diff
^=
num
;
diff
&=
-
diff
;
for
(
int
num
:
nums
)
{
if
((
num
&
diff
)
==
0
)
num1
[
0
]
^=
num
;
else
num2
[
0
]
^=
num
;
}
}
```
# 57.1 和为 S 的两个数字
...
...
@@ -2450,7 +2466,8 @@ diff &= -diff 得到出 diff 最右侧不为 0 的位,也就是不存在重复
-
如果 sum < target,移动较小的元素,使 sum 变大一些。
```
java
public
ArrayList
<
Integer
>
FindNumbersWithSum
(
int
[]
array
,
int
sum
)
{
public
ArrayList
<
Integer
>
FindNumbersWithSum
(
int
[]
array
,
int
sum
)
{
int
i
=
0
,
j
=
array
.
length
-
1
;
while
(
i
<
j
)
{
int
cur
=
array
[
i
]
+
array
[
j
];
...
...
@@ -2471,7 +2488,7 @@ public ArrayList<Integer> FindNumbersWithSum(int[] array, int sum) {
## 题目描述
输出所有和为 S 的连续正数序列。
序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
输出所有和为 S 的连续正数序列。
例如和为 100 的连续序列有:
...
...
@@ -2483,7 +2500,8 @@ public ArrayList<Integer> FindNumbersWithSum(int[] array, int sum) {
## 解题思路
```
java
public
ArrayList
<
ArrayList
<
Integer
>>
FindContinuousSequence
(
int
sum
)
{
public
ArrayList
<
ArrayList
<
Integer
>>
FindContinuousSequence
(
int
sum
)
{
ArrayList
<
ArrayList
<
Integer
>>
ret
=
new
ArrayList
<>();
int
start
=
1
,
end
=
2
;
int
curSum
=
3
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录