Skip to content

Commit 2f8121e

Browse files
committed
更新题解
1 parent e03c743 commit 2f8121e

39 files changed

+1331
-492
lines changed

algorithms/1-100/22.generate-parentheses.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,8 @@
1-
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
1+
#### [剑指 Offer II 085. 生成匹配的括号](https://leetcode-cn.com/problems/IDBivT/)
22

3-
```cpp
4-
例如,给出 n = 3,生成结果为:
5-
6-
[
7-
"((()))",
8-
"(()())",
9-
"(())()",
10-
"()(())",
11-
"()()()"
12-
]
13-
```
143

15-
---
164

17-
## DFS
5+
#### DFS
186

197
记录左括号和右括号的个数
208

@@ -39,10 +27,23 @@ public:
3927
};
4028
```
4129
30+
31+
4232
## 二进制枚举
4333
4434
1代表'(',0代表')', 以n=3为例,枚举从101010到111000之间所有合适的
4535
36+
- 0和1的个数相同
37+
38+
39+
40+
41+
4642
## 卡特兰数
4743
44+
45+
4846
## 动态规划
47+
48+
49+

algorithms/1-100/38.count-and-say.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,54 @@
1616

1717
注意:整数顺序将表示为一个字符串。
1818

19+
20+
21+
22+
1923
---
2024

25+
26+
27+
**外观数列**
28+
29+
30+
31+
**解题思路**
32+
33+
字符串遍历
34+
35+
36+
37+
**代码实现**
38+
39+
40+
41+
java
42+
43+
```java
44+
class Solution {
45+
public String countAndSay(int n) {
46+
String s = "1";
47+
for (int i = 1; i < n; i++) {
48+
StringBuilder sb = new StringBuilder();
49+
for (int j = 0; j < s.length();) {
50+
int k = j;
51+
while (k < s.length() && s.charAt(k) == s.charAt(j)) k++;
52+
sb.append(k - j);
53+
sb.append(s.charAt(j));
54+
j = k;
55+
}
56+
s = sb.toString();
57+
}
58+
return s;
59+
}
60+
}
61+
```
62+
63+
64+
65+
c++
66+
2167
```cpp
2268
class Solution {
2369
public:

algorithms/1-100/97.interleaving-string.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
### 序列型动态规划
1717

18-
dp[i][j]表示s3[0, i+j)是否可以用s1[0,i)和s2[0,j)交错组成
18+
`dp[i][j]`表示`s3[0, i+j)`是否可以用`s1[0,i)``s2[0,j)`交错组成
1919

2020
在序列前面补空字符
2121

algorithms/101-200/131.palindrome-partitioning.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
## 思路
2020

21-
1. 动态规划求子问题 f(i, j)表示i到j是否回文子串
21+
1. 动态规划求子问题 `f(i, j)`表示i到j是否回文子串
2222
2. dfs求所有可能性
2323

2424
## 代码实现

algorithms/101-200/132.palindrome-partitioning-ii.md

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
1-
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
1+
#### [剑指 Offer II 094. 最少回文分割](https://leetcode-cn.com/problems/omKAoA/)
22

3-
返回符合要求的最少分割次数。
43

5-
```cpp
6-
示例:
74

8-
输入: "aab" 输出: 1 解释: 进行一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。
9-
```
105

11-
---
126

137
## 动态规划
148

159
最优子结构:
1610

17-
g[i][j]表示范围[i, j]是否为回文串
1811

19-
dp[i]表示范围[0,i]需要分割的最小次数; 划分型动态规划
12+
13+
`g[i][j]`表示范围`[i, j]`是否为回文串
14+
15+
`dp[i]`表示范围`[0,i]`需要分割的最小次数; 划分型动态规划
2016

2117
状态转换方程:
2218

2319
- for i ∈ [0, n-1]
24-
- for j ∈ [0, i], 分割成[0,j-1][j,i]两部分
25-
- 如果 g[j][i], 则`dp[i] = min(dp[i], dp[j-1] + 1)`; 注意边界情况:j=0时,特殊处理
20+
- for j ∈ [0, i], 分割成`[0,j-1]``[j,i]`两部分
21+
- 如果 g[j][i], 则`dp[i] = min(dp[i], dp[j-1] + 1)`; 注意边界情况:`j=0`时,特殊处理
22+
23+
2624

2725
## 代码实现
2826

@@ -44,8 +42,8 @@ public:
4442
for (int i = 0; i < n; i++){
4543
dp[i] = i;
4644
for (int j = 0; j <= i; j++){
47-
if (g[j][i]) { // 分割成[0,j-1], [j, i]两部分
48-
if (j==0 ) dp[i] = 0;
45+
if (g[j][i]) { // 分割成 [0,j-1], [j, i]两部分
46+
if (j==0) dp[i] = 0;
4947
else dp[i] = min(dp[i], dp[j-1] + 1);
5048
}
5149
}

algorithms/101-200/136.single-number.md

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,8 @@
1-
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
1+
#### [136. 只出现一次的数字](https://leetcode-cn.com/problems/single-number/)
22

3-
说明:
43

5-
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
64

7-
```cpp
8-
示例 1:
9-
10-
输入: [2,2,1]
11-
输出: 1
12-
示例 2:
13-
14-
输入: [4,1,2,1,2]
15-
输出: 4
16-
```
17-
18-
---
19-
20-
### 解题思路
5+
#### 解题思路
216

227
异或运算
238

@@ -51,3 +36,20 @@ var singleNumber = function(nums) {
5136
return ans
5237
};
5338
```
39+
40+
41+
42+
java
43+
44+
```java
45+
class Solution {
46+
public int singleNumber(int[] nums) {
47+
int ans = 0;
48+
for (int x: nums) {
49+
ans ^= x;
50+
}
51+
return ans;
52+
}
53+
}
54+
```
55+

algorithms/101-200/137.single-number-ii.md

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
1+
#### [137. 只出现一次的数字 II](https://leetcode-cn.com/problems/single-number-ii/)
22

3-
说明:
43

5-
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
64

7-
```cpp
8-
示例 1:
5+
#### **哈希表**
96

10-
输入: [2,2,3,2]
11-
输出: 3
12-
```
7+
- 记录 map(数字,出现次数)
8+
- 遍历map,输出出现次数为1的数字
139

14-
---
10+
此解法相信大家都能想到,我们这里不做赘述
1511

16-
### 模拟三进制
12+
#### 模拟三进制
1713

1814
1. 记录每一位不为0的数字出现的次数
1915
2. 如果出现的次数对3取模为1,则说明只出现一次的数字此位也是1
2016
3. 将所有模3为1的位想加,得到最终结果
2117

18+
19+
20+
cpp
21+
2222
```cpp
2323
class Solution {
2424
public:
@@ -36,7 +36,37 @@ public:
3636
};
3737
```
3838
39-
### 状态机
39+
Java
40+
41+
```java
42+
class Solution {
43+
public int singleNumber(int[] nums) {
44+
int ans = 0;
45+
for (int i = 0; i < 32; i++) {
46+
int cnt = 0;
47+
for (int x : nums) {
48+
if (((x >>> i) &1)== 1) cnt++;
49+
}
50+
if (cnt % 3 == 1) ans += (1 << i);
51+
}
52+
return ans;
53+
}
54+
}
55+
```
56+
57+
java需要注意负数移位操作左移时溢出的情况,对于负数的移位要使用无符号右移避免溢出
58+
59+
java的三种移位符号
60+
61+
1. `>>` 是带符号右移,若左操作数是正数,则高位补“0”,若左操作数是负数,则高位补“1”.
62+
63+
2. `<<` 将左操作数向左边移动,并且在低位补0.
64+
65+
3. `>>>` 是无符号右移,无论左操作数是正数还是负数,在高位都补“0”
66+
67+
68+
69+
### DFA
4070

4171
初始:0 0
4272
1个1:1 0
@@ -56,3 +86,4 @@ public:
5686
}
5787
};
5888
```
89+

algorithms/101-200/141.linked-list-cycle.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
给定一个链表,判断链表中是否有环。
1+
#### [141. 环形链表](https://leetcode-cn.com/problems/linked-list-cycle/)
22

33
---
44

5-
## 借助hash表
5+
#### 借助hash表
66

77
```javascript
88
var hasCycle = function (head) {
@@ -18,8 +18,24 @@ var hasCycle = function (head) {
1818
};
1919
```
2020

21-
## 快慢指针
21+
#### 快慢指针
2222

2323
快指针每次移动两步,慢指针每次移动一步
2424

2525
如果存在环,快指针与慢指针就会相遇,否则快指针会到达链表结尾
26+
27+
```java
28+
public class Solution {
29+
public boolean hasCycle(ListNode head) {
30+
if (head== null || head.next ==null)return false;
31+
ListNode fast = head.next.next, slow = head.next;
32+
while (fast != slow) {
33+
if (fast == null || fast.next ==null) return false;
34+
fast = fast.next.next;
35+
slow = slow.next;
36+
}
37+
return true;
38+
}
39+
}
40+
```
41+

0 commit comments

Comments
 (0)