Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wushizhenking
CS-Notes
提交
6c274c42
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,发现更多精彩内容 >>
提交
6c274c42
编写于
4月 25, 2018
作者:
C
CyC2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
auto commit
上级
ae1e1404
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
126 addition
and
82 deletion
+126
-82
notes/Leetcode 题解.md
notes/Leetcode 题解.md
+1
-1
notes/剑指 offer 题解.md
notes/剑指 offer 题解.md
+124
-80
notes/正则表达式.md
notes/正则表达式.md
+1
-1
未找到文件。
notes/Leetcode 题解.md
浏览文件 @
6c274c42
...
...
@@ -263,7 +263,7 @@ Output: 1
```
java
public
int
findMin
(
int
[]
nums
)
{
int
l
=
0
,
h
=
nums
.
length
;
int
l
=
0
,
h
=
nums
.
length
-
1
;
while
(
l
<
h
)
{
int
m
=
l
+
(
h
-
l
)
/
2
;
if
(
nums
[
m
]
<=
nums
[
h
])
h
=
m
;
...
...
notes/剑指 offer 题解.md
浏览文件 @
6c274c42
...
...
@@ -909,15 +909,15 @@ public ListNode deleteNode(ListNode head, ListNode tobeDelete) {
```
java
public
ListNode
deleteDuplication
(
ListNode
pHead
)
{
if
(
pHead
==
null
)
return
null
;
if
(
pHead
==
null
||
pHead
.
next
==
null
)
return
pHead
;
ListNode
next
=
pHead
.
next
;
if
(
next
==
null
)
return
pHead
;
if
(
pHead
.
val
==
next
.
val
)
{
while
(
next
!=
null
&&
pHead
.
val
==
next
.
val
)
next
=
next
.
next
;
return
deleteDuplication
(
next
);
}
else
{
pHead
.
next
=
deleteDuplication
(
pHead
.
next
);
return
pHead
;
}
pHead
.
next
=
deleteDuplication
(
pHead
.
next
);
return
pHead
;
}
```
...
...
@@ -2256,6 +2256,8 @@ private int height(TreeNode root) {
## 题目描述
[
NowCoder
](
https://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=13&tqId=11193&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
)
一个整型数组里除了两个数字之外,其他的数字都出现了两次,找出这两个数。
## 解题思路
...
...
@@ -2267,40 +2269,49 @@ private int height(TreeNode root) {
diff &= -diff 得到出 diff 最右侧不为 0 的位,也就是不存在重复的两个元素在位级表示上最右侧不同的那一位,利用这一位就可以将两个元素区分开来。
```
java
public
void
FindNumsAppearOnce
(
int
[]
array
,
int
num1
[],
int
num2
[])
{
int
diff
=
0
;
for
(
int
num
:
array
)
diff
^=
num
;
// 得到最右一位
diff
&=
-
diff
;
for
(
int
num
:
array
)
{
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 的两个数字
## 题目描述
[
NowCoder
](
https://www.nowcoder.com/practice/390da4f7a00f44bea7c2f3d19491311b?tpId=13&tqId=11195&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
)
输入一个递增排序的数组和一个数字 S,在数组中查找两个数,使得他们的和正好是 S,如果有多对数字的和等于 S,输出两个数的乘积最小的。
## 解题思路
使用双指针,一个指针指向元素较小的值,一个指针指向元素较大的值。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。
如果两个指针指向元素的和 sum == target,那么得到要求的结果;如果 sum > target,移动较大的元素,使 sum 变小一些;如果 sum < target,移动较小的元素,使 sum 变大一些。
-
如果两个指针指向元素的和 sum == target,那么得到要求的结果;
-
如果 sum > target,移动较大的元素,使 sum 变小一些;
-
如果 sum < target,移动较小的元素,使 sum 变大一些。
```
java
public
ArrayList
<
Integer
>
FindNumbersWithSum
(
int
[]
array
,
int
sum
)
{
int
i
=
0
,
j
=
array
.
length
-
1
;
while
(
i
<
j
)
{
int
cur
=
array
[
i
]
+
array
[
j
];
if
(
cur
==
sum
)
return
new
ArrayList
<
Integer
>(
Arrays
.
asList
(
array
[
i
],
array
[
j
]));
else
if
(
cur
<
sum
)
i
++;
if
(
cur
==
sum
)
return
new
ArrayList
<>(
Arrays
.
asList
(
array
[
i
],
array
[
j
]));
if
(
cur
<
sum
)
i
++;
else
j
--;
}
return
new
ArrayList
<
Integer
>();
return
new
ArrayList
<>();
}
```
...
...
@@ -2308,32 +2319,41 @@ public ArrayList<Integer> FindNumbersWithSum(int[] array, int sum) {
## 题目描述
和为 100 的连续序列有 18, 19, 20, 21, 22。
[
NowCoder
](
https://www.nowcoder.com/practice/c451a3fd84b64cb19485dad758a55ebe?tpId=13&tqId=11194&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
)
输出所有和为 S 的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
例如和为 100 的连续序列有:
```
[9, 10, 11, 12, 13, 14, 15, 16]
[18, 19, 20, 21, 22]。
```
## 解题思路
```
java
public
ArrayList
<
ArrayList
<
Integer
>>
FindContinuousSequence
(
int
sum
)
{
ArrayList
<
ArrayList
<
Integer
>>
ret
=
new
ArrayList
<>();
int
first
=
1
,
last
=
2
;
int
start
=
1
,
end
=
2
;
int
curSum
=
3
;
while
(
first
<=
sum
/
2
&&
last
<
sum
)
{
while
(
end
<
sum
)
{
if
(
curSum
>
sum
)
{
curSum
-=
firs
t
;
firs
t
++;
curSum
-=
star
t
;
star
t
++;
}
else
if
(
curSum
<
sum
)
{
last
++;
curSum
+=
last
;
end
++;
curSum
+=
end
;
}
else
{
ArrayList
<
Integer
>
list
=
new
ArrayList
<>();
for
(
int
i
=
first
;
i
<=
last
;
i
++)
{
for
(
int
i
=
start
;
i
<=
end
;
i
++)
{
list
.
add
(
i
);
}
ret
.
add
(
list
);
curSum
-=
firs
t
;
firs
t
++;
last
++;
curSum
+=
last
;
curSum
-=
star
t
;
star
t
++;
end
++;
curSum
+=
end
;
}
}
return
ret
;
...
...
@@ -2350,11 +2370,14 @@ public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
## 解题思路
题目应该有一个隐含条件,就是不能用额外的空间。虽然 Java 的题目输入参数为 String 类型,需要先创建一个字符数组使得空间复杂度为 O(n),但是正确的参数类型应该和原书一样,为字符数组,并且只能使用该字符数组的空间。任何使用了额外空间的解法在面试时都会大打折扣,包括递归解法。正确的解法应该是和书上一样,先旋转每个单词,再旋转整个字符串。
[
NowCoder
](
https://www.nowcoder.com/practice/3194a4f4cf814f63919d0790578d51f3?tpId=13&tqId=11197&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
)
题目应该有一个隐含条件,就是不能用额外的空间。虽然 Java 的题目输入参数为 String 类型,需要先创建一个字符数组使得空间复杂度为 O(N),但是正确的参数类型应该和原书一样,为字符数组,并且只能使用该字符数组的空间。任何使用了额外空间的解法在面试时都会大打折扣,包括递归解法。
正确的解法应该是和书上一样,先旋转每个单词,再旋转整个字符串。
```
java
public
String
ReverseSentence
(
String
str
)
{
if
(
str
.
length
()
==
0
)
return
str
;
int
n
=
str
.
length
();
char
[]
chars
=
str
.
toCharArray
();
int
i
=
0
,
j
=
0
;
...
...
@@ -2370,43 +2393,59 @@ public String ReverseSentence(String str) {
}
private
void
reverse
(
char
[]
c
,
int
i
,
int
j
)
{
while
(
i
<
j
)
{
char
t
=
c
[
i
];
c
[
i
]
=
c
[
j
];
c
[
j
]
=
t
;
i
++;
j
--;
while
(
i
<
j
)
{
swap
(
c
,
i
++,
j
--);
}
}
private
void
swap
(
char
[]
c
,
int
i
,
int
j
)
{
char
t
=
c
[
i
];
c
[
i
]
=
c
[
j
];
c
[
j
]
=
t
;
}
```
# 58.2 左旋转字符串
## 题目描述
[
NowCoder
](
https://www.nowcoder.com/practice/12d959b108cb42b1ab72cef4d36af5ec?tpId=13&tqId=11196&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
)
对于一个给定的字符序列 S,请你把其循环左移 K 位后的序列输出。例如,字符序列 S=”abcXYZdef”, 要求输出循环左移 3 位后的结果,即“XYZdefabc”。
## 解题思路
将 "abcXYZdef" 旋转左移三位,可以先将 "abc" 和 "XYZdef" 分别旋转,得到 "cbafedZYX",然后再把整个字符串旋转得到 "XYZdefabc"。
```
java
public
String
LeftRotateString
(
String
str
,
int
n
)
{
if
(
str
.
length
()
==
0
)
return
""
;
char
[]
c
=
str
.
toCharArray
();
reverse
(
c
,
0
,
n
-
1
);
reverse
(
c
,
n
,
c
.
length
-
1
);
reverse
(
c
,
0
,
c
.
length
-
1
);
return
new
String
(
c
);
if
(
n
>=
str
.
length
())
return
str
;
char
[]
c
hars
=
str
.
toCharArray
();
reverse
(
c
hars
,
0
,
n
-
1
);
reverse
(
c
hars
,
n
,
chars
.
length
-
1
);
reverse
(
c
hars
,
0
,
chars
.
length
-
1
);
return
new
String
(
c
hars
);
}
private
void
reverse
(
char
[]
c
,
int
i
,
int
j
)
{
while
(
i
<
j
)
{
char
t
=
c
[
i
];
c
[
i
]
=
c
[
j
];
c
[
j
]
=
t
;
i
++;
j
--;
private
void
reverse
(
char
[]
chars
,
int
i
,
int
j
)
{
while
(
i
<
j
)
{
swap
(
chars
,
i
++,
j
--);
}
}
private
void
swap
(
char
[]
chars
,
int
i
,
int
j
)
{
char
t
=
chars
[
i
];
chars
[
i
]
=
chars
[
j
];
chars
[
j
]
=
t
;
}
```
# 59. 滑动窗口的最大值
## 题目描述
[
NowCoder
](
https://www.nowcoder.com/practice/1624bc35a45c42c0bc17d17fa0cba788?tpId=13&tqId=11217&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
)
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组 {2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小 3,那么一共存在 6 个滑动窗口,他们的最大值分别为 {4, 4, 6, 6, 6, 5}。
## 解题思路
...
...
@@ -2414,14 +2453,13 @@ private void reverse(char[] c, int i, int j) {
```
java
public
ArrayList
<
Integer
>
maxInWindows
(
int
[]
num
,
int
size
)
{
ArrayList
<
Integer
>
ret
=
new
ArrayList
<>();
if
(
size
>
num
.
length
||
size
<
1
)
return
ret
;
// 构建最大堆,即堆顶元素是堆的最大值。
PriorityQueue
<
Integer
>
heap
=
new
PriorityQueue
<
Integer
>((
o1
,
o2
)
->
o2
-
o1
);
if
(
size
>
num
.
length
||
size
<
1
)
return
ret
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
heap
.
add
(
num
[
i
]);
ret
.
add
(
heap
.
peek
());
for
(
int
i
=
1
;
i
+
size
-
1
<
num
.
length
;
i
++)
{
for
(
int
i
=
1
,
j
=
i
+
size
-
1
;
j
<
num
.
length
;
i
++,
j
++)
{
heap
.
remove
(
num
[
i
-
1
]);
heap
.
add
(
num
[
i
+
size
-
1
]);
heap
.
add
(
num
[
j
]);
ret
.
add
(
heap
.
peek
());
}
return
ret
;
...
...
@@ -2432,35 +2470,39 @@ public ArrayList<Integer> maxInWindows(int[] num, int size) {
## 题目描述
[
Lintcode
](
https://www.lintcode.com/en/problem/dices-sum/
)
把 n 个骰子仍在地上,求点数和为 s 的概率。
## 解题思路
### 动态规划解法
使用一个二维数组 dp 存储点数出现的次数,其中 dp
[
i
][
j
]
表示前 i 个骰子产生点数 j 的次数。
空间复杂度:O(N
<sup>
2
</sup>
)
```
java
private
static
int
face
=
6
;
public
double
countProbability
(
int
n
,
int
s
)
{
if
(
n
<
1
||
s
<
n
)
return
0.0
;
int
pointNum
=
face
*
n
;
int
[][]
dp
=
new
int
[
n
][
pointNum
];
for
(
int
i
=
0
;
i
<
face
;
i
++)
{
dp
[
0
][
i
]
=
1
;
public
List
<
Map
.
Entry
<
Integer
,
Double
>>
dicesSum
(
int
n
)
{
final
int
face
=
6
;
final
int
pointNum
=
face
*
n
;
long
[][]
dp
=
new
long
[
n
+
1
][
pointNum
+
1
];
for
(
int
i
=
1
;
i
<=
face
;
i
++)
{
dp
[
1
][
i
]
=
1
;
}
for
(
int
i
=
1
;
i
<
n
;
i
++)
{
for
(
int
j
=
i
;
j
<
pointNum
;
j
++)
{
// 使用 i 个骰子最小点数为 i
for
(
int
k
=
1
;
k
<=
face
;
k
++)
{
if
(
j
-
k
>=
0
)
{
dp
[
i
][
j
]
+=
dp
[
i
-
1
][
j
-
k
];
}
for
(
int
i
=
2
;
i
<=
n
;
i
++)
{
for
(
int
j
=
i
;
j
<=
pointNum
;
j
++)
{
// 使用 i 个骰子最小点数为 i
for
(
int
k
=
1
;
k
<=
face
&&
k
<=
j
;
k
++)
{
dp
[
i
][
j
]
+=
dp
[
i
-
1
][
j
-
k
];
}
}
}
int
totalNum
=
(
int
)
Math
.
pow
(
6
,
n
);
return
(
double
)
dp
[
n
-
1
][
s
-
1
]
/
totalNum
;
final
double
totalNum
=
Math
.
pow
(
6
,
n
);
List
<
Map
.
Entry
<
Integer
,
Double
>>
ret
=
new
ArrayList
<>();
for
(
int
i
=
n
;
i
<=
pointNum
;
i
++)
{
ret
.
add
(
new
AbstractMap
.
SimpleEntry
<>(
i
,
dp
[
n
][
i
]
/
totalNum
));
}
return
ret
;
}
```
...
...
@@ -2469,28 +2511,30 @@ public double countProbability(int n, int s) {
空间复杂度:O(N)
```
java
private
static
int
face
=
6
;
public
double
countProbability
(
int
n
,
int
s
)
{
if
(
n
<
1
||
s
<
n
)
return
0.0
;
int
pointNum
=
face
*
n
;
int
[][]
dp
=
new
int
[
2
][
pointNum
];
for
(
int
i
=
0
;
i
<
face
;
i
++)
{
public
List
<
Map
.
Entry
<
Integer
,
Double
>>
dicesSum
(
int
n
)
{
final
int
face
=
6
;
final
int
pointNum
=
face
*
n
;
long
[][]
dp
=
new
long
[
2
][
pointNum
+
1
];
for
(
int
i
=
1
;
i
<=
face
;
i
++)
{
dp
[
0
][
i
]
=
1
;
}
int
flag
=
1
;
for
(
int
i
=
1
;
i
<
n
;
i
++)
{
for
(
int
j
=
i
;
j
<
pointNum
;
j
++)
{
// 使用 i 个骰子最小点数为 i
for
(
int
k
=
1
;
k
<=
face
;
k
++)
{
if
(
j
-
k
>=
0
)
{
dp
[
flag
][
j
]
+=
dp
[
1
-
flag
][
j
-
k
];
}
for
(
int
i
=
2
;
i
<=
n
;
i
++,
flag
=
1
-
flag
)
{
for
(
int
j
=
0
;
j
<=
pointNum
;
j
++)
{
dp
[
flag
][
j
]
=
0
;
// 旋转数组清零
}
for
(
int
j
=
i
;
j
<=
pointNum
;
j
++)
{
// 使用 i 个骰子最小点数为 i
for
(
int
k
=
1
;
k
<=
face
&&
k
<=
j
;
k
++)
{
dp
[
flag
][
j
]
+=
dp
[
1
-
flag
][
j
-
k
];
}
}
flag
=
1
-
flag
;
}
int
totalNum
=
(
int
)
Math
.
pow
(
6
,
n
);
return
(
double
)
dp
[
flag
][
s
-
1
]
/
totalNum
;
final
double
totalNum
=
Math
.
pow
(
6
,
n
);
List
<
Map
.
Entry
<
Integer
,
Double
>>
ret
=
new
ArrayList
<>();
for
(
int
i
=
n
;
i
<=
pointNum
;
i
++)
{
ret
.
add
(
new
AbstractMap
.
SimpleEntry
<>(
i
,
dp
[
1
-
flag
][
i
]
/
totalNum
));
}
return
ret
;
}
```
...
...
notes/正则表达式.md
浏览文件 @
6c274c42
...
...
@@ -328,7 +328,7 @@ aBCd
# 九、前后查找
前后查找规定了匹配的内容首尾应该匹配的内容,但是又不包含首尾匹配的内容。向前查找用
**?=**
来定义,它规定了尾部匹配的内容,这个匹配的内容在 ?= 之后定义。所谓向前查找,就是规定了一个匹配的内容,然后以这个内容为尾部向前面查找需要匹配的内容。向后匹配用 ?<= 定义(注:
javaScript不支持向后匹配,java
对其支持也不完善)。
前后查找规定了匹配的内容首尾应该匹配的内容,但是又不包含首尾匹配的内容。向前查找用
**?=**
来定义,它规定了尾部匹配的内容,这个匹配的内容在 ?= 之后定义。所谓向前查找,就是规定了一个匹配的内容,然后以这个内容为尾部向前面查找需要匹配的内容。向后匹配用 ?<= 定义(注:
javaScript 不支持向后匹配, java
对其支持也不完善)。
**应用**
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录