Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 734f624

Browse files
authored
Merge branch 'master' into master
2 parents 5da4a7e + 861c770 commit 734f624

30 files changed

+1312
-556
lines changed

‎README.md

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -299,24 +299,25 @@
299299
<img src='https://code-thinking.cdn.bcebos.com/pics/动态规划-背包问题总结.png' width=500 alt='背包问题大纲'> </img></div>
300300

301301

302-
11. [动态规划:01背包理论基础](./problems/背包理论基础01背包-1.md)
303-
12. [动态规划:01背包理论基础(滚动数组)](./problems/背包理论基础01背包-2.md)
302+
11. [动态规划:01背包理论基础(二维dp数组)](./problems/背包理论基础01背包-1.md)
303+
12. [动态规划:01背包理论基础(一维dp数组)](./problems/背包理论基础01背包-2.md)
304304
13. [动态规划:416.分割等和子集](./problems/0416.分割等和子集.md)
305305
14. [动态规划:1049.最后一块石头的重量II](./problems/1049.最后一块石头的重量II.md)
306306
15. [本周小结!(动态规划系列三)](./problems/周总结/20210121动规周末总结.md)
307307
16. [动态规划:494.目标和](./problems/0494.目标和.md)
308308
17. [动态规划:474.一和零](./problems/0474.一和零.md)
309-
18. [动态规划:完全背包总结篇](./problems/背包问题理论基础完全背包.md)
310-
19. [动态规划:518.零钱兑换II](./problems/0518.零钱兑换II.md)
311-
20. [本周小结!(动态规划系列四)](./problems/周总结/20210128动规周末总结.md)
312-
21. [动态规划:377.组合总和IV](./problems/0377.组合总和IV.md)
313-
22. [动态规划:70.爬楼梯(完全背包版本)](./problems/0070.爬楼梯完全背包版本.md)
314-
23. [动态规划:322.零钱兑换](./problems/0322.零钱兑换.md)
315-
24. [动态规划:279.完全平方数](./problems/0279.完全平方数.md)
316-
25. [本周小结!(动态规划系列五)](./problems/周总结/20210204动规周末总结.md)
317-
26. [动态规划:139.单词拆分](./problems/0139.单词拆分.md)
318-
27. [动态规划:多重背包理论基础](./problems/背包问题理论基础多重背包.md)
319-
28. [背包问题总结篇](./problems/背包总结篇.md)
309+
18. [动态规划:完全背包理论基础(二维dp数组)](./problems/背包问题理论基础完全背包.md)
310+
19. [动态规划:完全背包理论基础(一维dp数组)](./problems/背包问题完全背包一维.md)
311+
20. [动态规划:518.零钱兑换II](./problems/0518.零钱兑换II.md)
312+
21. [本周小结!(动态规划系列四)](./problems/周总结/20210128动规周末总结.md)
313+
22. [动态规划:377.组合总和IV](./problems/0377.组合总和IV.md)
314+
23. [动态规划:70.爬楼梯(完全背包版本)](./problems/0070.爬楼梯完全背包版本.md)
315+
24. [动态规划:322.零钱兑换](./problems/0322.零钱兑换.md)
316+
25. [动态规划:279.完全平方数](./problems/0279.完全平方数.md)
317+
26. [本周小结!(动态规划系列五)](./problems/周总结/20210204动规周末总结.md)
318+
27. [动态规划:139.单词拆分](./problems/0139.单词拆分.md)
319+
28. [动态规划:多重背包理论基础](./problems/背包问题理论基础多重背包.md)
320+
29. [背包问题总结篇](./problems/背包总结篇.md)
320321

321322
打家劫舍系列:
322323

@@ -408,21 +409,6 @@
408409

409410
(持续更新中....)
410411

411-
412-
## 十大排序
413-
414-
## 数论
415-
416-
## 高级数据结构经典题目
417-
418-
* 并查集
419-
* 最小生成树
420-
* 线段树
421-
* 树状数组
422-
* 字典树
423-
424-
## 海量数据处理
425-
426412
# 补充题目
427413

428414
以上题目是重中之重,大家至少要刷两遍以上才能彻底理解,如果熟练以上题目之后还在找其他题目练手,可以再刷以下题目:

‎problems/0018.四数之和.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
四数之和,和[15.三数之和](https://programmercarl.com/0015.三数之和.html)是一个思路,都是使用双指针法, 基本解法就是在[15.三数之和](https://programmercarl.com/0015.三数之和.html) 的基础上再套一层for循环。
3737

38-
但是有一些细节需要注意,例如: 不要判断`nums[k] > target` 就返回了,三数之和 可以通过 `nums[i] > 0` 就返回了,因为 0 已经是确定的数了,四数之和这道题目 target是任意值。比如:数组是`[-4, -3, -2, -1]`,`target``-10`,不能因为`-4 > -10`而跳过。但是我们依旧可以去做剪枝,逻辑变成`nums[i] > target && (nums[i] >=0 || target >= 0)`就可以了。
38+
但是有一些细节需要注意,例如: 不要判断`nums[k] > target` 就返回了,三数之和 可以通过 `nums[i] > 0` 就返回了,因为 0 已经是确定的数了,四数之和这道题目 target是任意值。比如:数组是`[-4, -3, -2, -1]`,`target``-10`,不能因为`-4 > -10`而跳过。但是我们依旧可以去做剪枝,逻辑变成`nums[k] > target && (nums[k] >=0 || target >= 0)`就可以了。
3939

4040
[15.三数之和](https://programmercarl.com/0015.三数之和.html)的双指针解法是一层for循环num[i]为确定值,然后循环内有left和right下标作为双指针,找到nums[i] + nums[left] + nums[right] == 0。
4141

@@ -253,7 +253,7 @@ public class Solution {
253253
for (int k = 0; k < nums.length; k++) {
254254
// 剪枝处理
255255
if (nums[k] > target && nums[k] >= 0) {
256-
break;
256+
break; // 此处的break可以等价于return result;
257257
}
258258
// 对nums[k]去重
259259
if (k > 0 && nums[k] == nums[k - 1]) {
@@ -262,7 +262,7 @@ public class Solution {
262262
for (int i = k + 1; i < nums.length; i++) {
263263
// 第二级剪枝
264264
if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) {
265-
break;
265+
break; // 注意是break到上一级for循环,如果直接return result;会有遗漏
266266
}
267267
// 对nums[i]去重
268268
if (i > k + 1 && nums[i] == nums[i - 1]) {
@@ -802,3 +802,4 @@ end
802802
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
803803
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
804804
</a>
805+

‎problems/0019.删除链表的倒数第N个节点.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,36 @@ class Solution {
129129
}
130130
```
131131

132+
133+
```java
134+
class Solution {
135+
public ListNode removeNthFromEnd(ListNode head, int n) {
136+
// 创建一个新的哑节点,指向原链表头
137+
ListNode s = new ListNode(-1, head);
138+
// 递归调用remove方法,从哑节点开始进行删除操作
139+
remove(s, n);
140+
// 返回新链表的头(去掉可能的哑节点)
141+
return s.next;
142+
}
143+
144+
public int remove(ListNode p, int n) {
145+
// 递归结束条件:如果当前节点为空,返回0
146+
if (p == null) {
147+
return 0;
148+
}
149+
// 递归深入到下一个节点
150+
int net = remove(p.next, n);
151+
// 如果当前节点是倒数第n个节点,进行删除操作
152+
if (net == n) {
153+
p.next = p.next.next;
154+
}
155+
// 返回当前节点的总深度
156+
return net + 1;
157+
}
158+
}
159+
```
160+
161+
132162
### Python:
133163

134164
```python

‎problems/0020.有效的括号.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,35 @@ class Solution {
166166
deque.pop();
167167
}
168168
}
169-
//最后判断栈中元素是否匹配
169+
//遍历结束,如果栈为空,则括号全部匹配
170170
return deque.isEmpty();
171171
}
172172
}
173173
```
174174

175+
```java
176+
// 解法二
177+
// 对应的另一半一定在栈顶
178+
class Solution {
179+
public boolean isValid(String s) {
180+
Stack<Character> stack = new Stack<>();
181+
for(char c : s.toCharArray()){
182+
// 有对应的另一半就直接消消乐
183+
if(c == ')' && !stack.isEmpty() && stack.peek() == '(')
184+
stack.pop();
185+
else if(c == '}' && !stack.isEmpty() && stack.peek() == '{')
186+
stack.pop();
187+
else if(c == ']' && !stack.isEmpty() && stack.peek() == '[')
188+
stack.pop();
189+
else
190+
stack.push(c);// 没有匹配的就放进去
191+
}
192+
193+
return stack.isEmpty();
194+
}
195+
}
196+
```
197+
175198
### Python:
176199

177200
```python
@@ -555,3 +578,4 @@ impl Solution {
555578
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
556579
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
557580
</a>
581+

‎problems/0059.螺旋矩阵II.md

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -715,26 +715,65 @@ object Solution {
715715
### C#:
716716

717717
```csharp
718-
public class Solution {
719-
public int[][] GenerateMatrix(int n) {
720-
int[][] answer = new int[n][];
721-
for(int i = 0; i < n; i++)
722-
answer[i] = new int[n];
723-
int start = 0;
724-
int end = n - 1;
725-
int tmp = 1;
726-
while(tmp < n * n)
718+
public int[][] GenerateMatrix(int n)
719+
{
720+
// 参考Carl的代码随想录里面C++的思路
721+
// https://www.programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html#%E6%80%9D%E8%B7%AF
722+
int startX = 0, startY = 0; // 定义每循环一个圈的起始位置
723+
int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
724+
int count = 1; // 用来给矩阵每个空格赋值
725+
int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
726+
int offset = 1;// 需要控制每一条边遍历的长度,每次循环右边界收缩一位
727+
728+
// 构建result二维数组
729+
int[][] result = new int[n][];
730+
for (int k = 0; k < n; k++)
731+
{
732+
result[k] = new int[n];
733+
}
734+
735+
int i = 0, j = 0; // [i,j]
736+
while (loop > 0)
737+
{
738+
i = startX;
739+
j = startY;
740+
// 四个For循环模拟转一圈
741+
// 第一排,从左往右遍历,不取最右侧的值(左闭右开)
742+
for (; j < n - offset; j++)
743+
{
744+
result[i][j] = count++;
745+
}
746+
// 右侧的第一列,从上往下遍历,不取最下面的值(左闭右开)
747+
for (; i < n - offset; i++)
748+
{
749+
result[i][j] = count++;
750+
}
751+
752+
// 最下面的第一行,从右往左遍历,不取最左侧的值(左闭右开)
753+
for (; j > startY; j--)
754+
{
755+
result[i][j] = count++;
756+
}
757+
758+
// 左侧第一列,从下往上遍历,不取最左侧的值(左闭右开)
759+
for (; i > startX; i--)
727760
{
728-
for(int i = start; i < end; i++) answer[start][i] = tmp++;
729-
for(int i = start; i < end; i++) answer[i][end] = tmp++;
730-
for(int i = end; i > start; i--) answer[end][i] = tmp++;
731-
for(int i = end; i > start; i--) answer[i][start] = tmp++;
732-
start++;
733-
end--;
734-
}
735-
if(n % 2 == 1) answer[n / 2][n / 2] = tmp;
736-
return answer;
761+
result[i][j] = count++;
762+
}
763+
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
764+
startX++;
765+
startY++;
766+
767+
// offset 控制每一圈里每一条边遍历的长度
768+
offset++;
769+
loop--;
770+
}
771+
if (n % 2 == 1)
772+
{
773+
// n 为奇数
774+
result[mid][mid] = count;
737775
}
776+
return result;
738777
}
739778
```
740779

‎problems/0070.爬楼梯.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ public:
130130
};
131131
```
132132
133-
* 时间复杂度:$O(n)$
134-
* 空间复杂度:$O(n)$
133+
* 时间复杂度:O(n)
134+
* 空间复杂度:O(n)
135135
136136
当然依然也可以,优化一下空间复杂度,代码如下:
137137
@@ -154,8 +154,8 @@ public:
154154
};
155155
```
156156

157-
* 时间复杂度:$O(n)$
158-
* 空间复杂度:$O(1)$
157+
* 时间复杂度:O(n)
158+
* 空间复杂度:O(1)
159159

160160
后面将讲解的很多动规的题目其实都是当前状态依赖前两个,或者前三个状态,都可以做空间上的优化,**但我个人认为面试中能写出版本一就够了哈,清晰明了,如果面试官要求进一步优化空间的话,我们再去优化**
161161

@@ -524,3 +524,4 @@ impl Solution {
524524
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
525525
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
526526
</a>
527+

‎problems/0102.二叉树的层序遍历.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,47 @@ impl Solution {
12311231
}
12321232
```
12331233

1234+
#### C#:
1235+
1236+
```C# 199.二叉树的右视图
1237+
public class Solution
1238+
{
1239+
public IList<int> RightSideView(TreeNode root)
1240+
{
1241+
var result = new List<int>();
1242+
Queue<TreeNode> queue = new();
1243+
1244+
if (root != null)
1245+
{
1246+
queue.Enqueue(root);
1247+
}
1248+
while (queue.Count > 0)
1249+
{
1250+
int count = queue.Count;
1251+
int lastValue = count - 1;
1252+
for (int i = 0; i < count; i++)
1253+
{
1254+
var currentNode = queue.Dequeue();
1255+
if (i == lastValue)
1256+
{
1257+
result.Add(currentNode.val);
1258+
}
1259+
1260+
// lastValue == i == count -1 : left 先于 right 进入Queue
1261+
if (currentNode.left != null) queue.Enqueue(currentNode.left);
1262+
if (currentNode.right != null) queue.Enqueue(currentNode.right);
1263+
1264+
//// lastValue == i == 0: right 先于 left 进入Queue
1265+
// if(currentNode.right !=null ) queue.Enqueue(currentNode.right);
1266+
// if(currentNode.left !=null ) queue.Enqueue(currentNode.left);
1267+
}
1268+
}
1269+
1270+
return result;
1271+
}
1272+
}
1273+
```
1274+
12341275
## 637.二叉树的层平均值
12351276

12361277
[力扣题目链接](https://leetcode.cn/problems/average-of-levels-in-binary-tree/)
@@ -1558,6 +1599,35 @@ impl Solution {
15581599
}
15591600
```
15601601

1602+
#### C#:
1603+
1604+
```C# 二叉树的层平均值
1605+
public class Solution {
1606+
public IList<double> AverageOfLevels(TreeNode root) {
1607+
var result= new List<double>();
1608+
Queue<TreeNode> queue = new();
1609+
if(root !=null) queue.Enqueue(root);
1610+
1611+
while (queue.Count > 0)
1612+
{
1613+
int count = queue.Count;
1614+
double value=0;
1615+
for (int i = 0; i < count; i++)
1616+
{
1617+
var curentNode=queue.Dequeue();
1618+
value += curentNode.val;
1619+
if (curentNode.left!=null) queue.Enqueue(curentNode.left);
1620+
if (curentNode.right!=null) queue.Enqueue(curentNode.right);
1621+
}
1622+
result.Add(value/count);
1623+
}
1624+
1625+
return result;
1626+
}
1627+
}
1628+
1629+
```
1630+
15611631
## 429.N叉树的层序遍历
15621632

15631633
[力扣题目链接](https://leetcode.cn/problems/n-ary-tree-level-order-traversal/)

‎problems/0111.二叉树的最小深度.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
本题依然是前序遍历和后序遍历都可以,前序求的是深度,后序求的是高度。
4141

4242
* 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
43-
* 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数后者节点数(取决于高度从0开始还是从1开始)
43+
* 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
4444

4545
那么使用后序遍历,其实求的是根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离 也同样是最小深度。
4646

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /