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 7a138de

Browse files
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
2 parents 82c7f09 + e5b75df commit 7a138de

File tree

7 files changed

+292
-62
lines changed

7 files changed

+292
-62
lines changed

‎problems/0112.路径总和.md

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -309,25 +309,25 @@ public:
309309
0112.路径总和
310310

311311
```java
312-
class solution {
313-
public boolean haspathsum(treenode root, int targetsum) {
312+
class Solution {
313+
public boolean hasPathSum(TreeNode root, int targetSum) {
314314
if (root == null) {
315315
return false;
316316
}
317-
targetsum -= root.val;
317+
targetSum -= root.val;
318318
// 叶子结点
319319
if (root.left == null && root.right == null) {
320-
return targetsum == 0;
320+
return targetSum == 0;
321321
}
322322
if (root.left != null) {
323-
boolean left = haspathsum(root.left, targetsum);
324-
if (left) { // 已经找到
323+
boolean left = hasPathSum(root.left, targetSum);
324+
if (left) { // 已经找到,提前返回
325325
return true;
326326
}
327327
}
328328
if (root.right != null) {
329-
boolean right = haspathsum(root.right, targetsum);
330-
if (right) { // 已经找到
329+
boolean right = hasPathSum(root.right, targetSum);
330+
if (right) { // 已经找到,提前返回
331331
return true;
332332
}
333333
}
@@ -336,39 +336,39 @@ class solution {
336336
}
337337

338338
// lc112 简洁方法
339-
class solution {
340-
public boolean haspathsum(treenode root, int targetsum) {
339+
class Solution {
340+
public boolean hasPathSum(TreeNode root, int targetSum) {
341341

342342
if (root == null) return false; // 为空退出
343343

344344
// 叶子节点判断是否符合
345-
if (root.left == null && root.right == null) return root.val == targetsum;
345+
if (root.left == null && root.right == null) return root.val == targetSum;
346346

347347
// 求两侧分支的路径和
348-
return haspathsum(root.left, targetsum - root.val) || haspathsum(root.right, targetsum - root.val);
348+
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
349349
}
350350
}
351351
```
352352

353353
迭代
354354

355355
```java
356-
class solution {
357-
public boolean haspathsum(treenode root, int targetsum) {
356+
class Solution {
357+
public boolean hasPathSum(TreeNode root, int targetSum) {
358358
if(root == null) return false;
359-
stack<treenode> stack1 = new stack<>();
360-
stack<integer> stack2 = new stack<>();
359+
Stack<TreeNode> stack1 = new Stack<>();
360+
Stack<Integer> stack2 = new Stack<>();
361361
stack1.push(root);
362362
stack2.push(root.val);
363-
while(!stack1.isempty()) {
363+
while(!stack1.isEmpty()) {
364364
int size = stack1.size();
365365

366366
for(int i = 0; i < size; i++) {
367-
treenode node = stack1.pop();
367+
TreeNode node = stack1.pop();
368368
int sum = stack2.pop();
369369

370370
// 如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回true
371-
if(node.left == null && node.right == null && sum == targetsum) {
371+
if(node.left == null && node.right == null && sum == targetSum) {
372372
return true;
373373
}
374374
// 右节点,压进去一个节点的时候,将该节点的路径数值也记录下来
@@ -387,8 +387,9 @@ class solution {
387387
}
388388
}
389389
```
390-
```Java 統一迭代法
391-
public boolean hasPathSum(TreeNode root, int targetSum) {
390+
```Java
391+
class Solution {
392+
public boolean hasPathSum(TreeNode root, int targetSum) {
392393
Stack<TreeNode> treeNodeStack = new Stack<>();
393394
Stack<Integer> sumStack = new Stack<>();
394395

@@ -422,38 +423,39 @@ class solution {
422423
}
423424
return false;
424425
}
426+
}
425427
```
426428

427429
0113.路径总和-ii
428430

429431
```java
430-
class solution {
431-
public List<List<Integer>> pathsum(TreeNode root, int targetsum) {
432+
class Solution {
433+
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
432434
List<List<Integer>> res = new ArrayList<>();
433435
if (root == null) return res; // 非空判断
434436

435437
List<Integer> path = new LinkedList<>();
436-
preorderdfs(root, targetsum, res, path);
438+
preOrderDfs(root, targetSum, res, path);
437439
return res;
438440
}
439441

440-
public void preorderdfs(TreeNode root, int targetsum, List<List<Integer>> res, List<Integer> path) {
442+
public void preOrderDfs(TreeNode root, int targetSum, List<List<Integer>> res, List<Integer> path) {
441443
path.add(root.val);
442444
// 遇到了叶子节点
443445
if (root.left == null && root.right == null) {
444446
// 找到了和为 targetsum 的路径
445-
if (targetsum - root.val == 0) {
447+
if (targetSum - root.val == 0) {
446448
res.add(new ArrayList<>(path));
447449
}
448450
return; // 如果和不为 targetsum,返回
449451
}
450452

451453
if (root.left != null) {
452-
preorderdfs(root.left, targetsum - root.val, res, path);
454+
preOrderDfs(root.left, targetSum - root.val, res, path);
453455
path.remove(path.size() - 1); // 回溯
454456
}
455457
if (root.right != null) {
456-
preorderdfs(root.right, targetsum - root.val, res, path);
458+
preOrderDfs(root.right, targetSum - root.val, res, path);
457459
path.remove(path.size() - 1); // 回溯
458460
}
459461
}
@@ -1626,3 +1628,4 @@ public class Solution {
16261628
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
16271629
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
16281630
</a>
1631+

‎problems/0474.一和零.md

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,70 @@ public:
261261

262262
## 其他语言版本
263263

264-
265264
### Java
265+
266+
三维DP数组实现
267+
268+
```java
269+
class Solution {
270+
public int findMaxForm(String[] strs, int m, int n) {
271+
/// 数组有三个维度
272+
// 第一个维度:取前面的几个字符串
273+
// 第二个维度:0的数量限制(背包维度 1 容量)
274+
// 第三个维度:1的数量限制(背包维度 2 容量)
275+
int[][][] dpArr = new int[strs.length][m + 1][n + 1];
276+
277+
/// 初始化dpArr数组
278+
// 计算第一个字符串的零数量和1数量
279+
int zeroNum = 0;
280+
int oneNum = 0;
281+
for (char c : strs[0].toCharArray()) {
282+
if (c == '0') {
283+
zeroNum++;
284+
} else {
285+
oneNum++;
286+
}
287+
}
288+
// 当0数量、1数量都容得下第一个字符串时,将DP数组的相应位置初始化为1,因为当前的子集数量为1
289+
for (int j = zeroNum; j <= m; j++) {
290+
for (int k = oneNum; k <= n; k++) {
291+
dpArr[0][j][k] = 1;
292+
}
293+
}
294+
/// 依次填充加入第i个字符串之后的DP数组
295+
for (int i = 1; i < strs.length; i++) {
296+
zeroNum = 0;
297+
oneNum = 0;
298+
for (char c : strs[i].toCharArray()) {
299+
if (c == '0') {
300+
zeroNum++;
301+
} else {
302+
oneNum++;
303+
}
304+
}
305+
for (int j = 0; j <= m; j++) {
306+
for (int k = 0; k <= n; k++) {
307+
if (j >= zeroNum && k >= oneNum) {
308+
// --if-- 当0数量维度和1数量维度的容量都大于等于当前字符串的0数量和1数量时,才考虑是否将当前字符串放入背包
309+
// 不放入第i个字符串,子集数量仍为 dpArr[i - 1][j][k]
310+
// 放入第i个字符串,需要在0维度腾出 zeroNum 个容量,1维度腾出 oneNum 个容量,然后放入当前字符串,即 dpArr[i - 1][j - zeroNum][k - oneNum] + 1)
311+
dpArr[i][j][k] = Math.max(dpArr[i - 1][j][k], dpArr[i - 1][j - zeroNum][k - oneNum] + 1);
312+
} else {
313+
// --if-- 无法放入第i个字符串,子集数量仍为 dpArr[i - 1][j][k]
314+
dpArr[i][j][k] = dpArr[i - 1][j][k];
315+
}
316+
}
317+
}
318+
}
319+
return dpArr[dpArr.length - 1][m][n];
320+
}
321+
}
322+
```
323+
324+
325+
326+
二维DP数组实现
327+
266328
```Java
267329
class Solution {
268330
public int findMaxForm(String[] strs, int m, int n) {
@@ -682,3 +744,4 @@ public class Solution
682744
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
683745
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
684746
</a>
747+

‎problems/0494.目标和.md

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -825,30 +825,69 @@ func abs(x int) int {
825825

826826
### JavaScript
827827
```javascript
828+
/**
829+
* 题目来源: {@link https://leetcode.cn/problems/target-sum/}
830+
*
831+
* 题解来源: {@link https://programmercarl.com/0494.%E7%9B%AE%E6%A0%87%E5%92%8C.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE}
832+
*
833+
* 时间复杂度: O(n * C), C 为数组元素总和与目标值之和的一半
834+
*
835+
* 空间复杂度: O(C)
836+
*
837+
* @param { number[] } nums
838+
* @param { number } target
839+
* @return { number }
840+
*/
828841
const findTargetSumWays = (nums, target) => {
829-
830-
const sum = nums.reduce((a, b) => a+b);
842+
// 原题目可转化为:
843+
//
844+
// 将所有元素划分为 2 个集合,
845+
// 一个集合中包含所有要添加 "+" 号的元素, 一个集合中包含所有要添加 "-" 号的元素
846+
//
847+
// 设两个集合的元素和分别为 positive 和 negative, 所有元素总和为 sum, 那么有如下等式:
848+
// positive + negative = sum (1)
849+
// positive - negative = target (2)
850+
// (1) 与 (2) 联立可得: positive = (sum + target) / 2,
851+
// 所以如果能从原数组中取出若干个元素形成 1 个元素总和为 (sum + target) / 2 的集合,
852+
// 就算得到了 1 种满足题意的组合方法
853+
//
854+
// 因此, 所求变为: 有多少种取法, 可使得容量为 (sum + target) / 2 的背包被装满?
855+
856+
const sum = nums.reduce((a, b) => a + b);
831857

832-
if(Math.abs(target) > sum) {
858+
if(Math.abs(target) > sum) {
833859
return 0;
834860
}
835861

836-
if((target + sum) % 2) {
862+
if((target + sum) % 2) {
837863
return 0;
838864
}
839865

840-
const halfSum = (target + sum) / 2;
841-
842-
let dp = new Array(halfSum+1).fill(0);
866+
const bagWeight = (target + sum) / 2;
867+
868+
// 1. dp 数组的含义
869+
// dp[j]: 装满容量为 j 的背包, 有 dp[j] 种方法
870+
let dp = new Array(bagWeight + 1).fill(0);
871+
872+
// 2. 递推公式
873+
// dp[j] = Σ(dp[j - nums[j]]), (j ∈ [0, j] 且 j >= nums[j])
874+
// 因为 dp[j - nums[j]] 表示: 装满容量为 j - nums[j] 背包有 dp[j - nums[j]] 种方法
875+
// 而容量为 j - nums[j] 的背包只需要再将 nums[j] 放入背包就能使得背包容量达到 j
876+
// 因此, 让背包容量达到 j 有 Σ(dp[j - nums[j]]) 种方法
877+
878+
// 3. dp 数组如何初始化
879+
// dp[0] = 1, dp[1 ~ bagWeight] = 0
843880
dp[0] = 1;
844-
845-
for(let i = 0; i < nums.length; i++) {
846-
for(let j = halfSum; j >= nums[i]; j--) {
881+
882+
// 4. 遍历顺序
883+
// 先物品后背包, 物品从前往后遍历, 背包容量从后往前遍历
884+
for (let i = 0; i < nums.length; i++) {
885+
for (let j = bagWeight; j >= nums[i]; j--) {
847886
dp[j] += dp[j - nums[i]];
848887
}
849888
}
850889

851-
return dp[halfSum];
890+
return dp[bagWeight];
852891
};
853892
```
854893

‎problems/0530.二叉搜索树的最小绝对差.md

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -153,23 +153,27 @@ public:
153153
递归
154154
```java
155155
class Solution {
156-
TreeNode pre;// 记录上一个遍历的结点
156+
TreeNode pre;// 记录上一个遍历的结点
157157
int result = Integer.MAX_VALUE;
158+
158159
public int getMinimumDifference(TreeNode root) {
159-
if(root==null)return 0;
160-
traversal(root);
161-
return result;
160+
if (root == null)
161+
return 0;
162+
traversal(root);
163+
return result;
162164
}
163-
public void traversal(TreeNode root){
164-
if(root==null)return;
165-
//左
165+
166+
public void traversal(TreeNode root) {
167+
if (root == null)
168+
return;
169+
// 左
166170
traversal(root.left);
167-
//中
168-
if(pre!=null){
169-
result = Math.min(result,root.val-pre.val);
171+
//中
172+
if(pre != null){
173+
result = Math.min(result,root.val - pre.val);
170174
}
171175
pre = root;
172-
//右
176+
//右
173177
traversal(root.right);
174178
}
175179
}
@@ -182,22 +186,27 @@ class Solution {
182186
TreeNode pre = null;
183187
int result = Integer.MAX_VALUE;
184188

185-
if(root != null)
189+
if(root != null)
186190
stack.add(root);
187-
while(!stack.isEmpty()){
191+
192+
// 中序遍历(左中右),由于栈先入后出,反序(右中左)
193+
while (!stack.isEmpty()) {
188194
TreeNode curr = stack.peek();
189-
if(curr != null){
195+
if(curr != null){
190196
stack.pop();
191-
if(curr.right != null)
197+
//
198+
if (curr.right != null)
192199
stack.add(curr.right);
200+
// 中(先用null标记)
193201
stack.add(curr);
194202
stack.add(null);
195-
if(curr.left != null)
203+
//
204+
if (curr.left != null)
196205
stack.add(curr.left);
197-
}else{
206+
}else { // 中(遇到null再处理)
198207
stack.pop();
199208
TreeNode temp = stack.pop();
200-
if(pre != null)
209+
if(pre != null)
201210
result = Math.min(result, temp.val - pre.val);
202211
pre = temp;
203212
}
@@ -674,3 +683,4 @@ public class Solution
674683
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
675684
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
676685
</a>
686+

0 commit comments

Comments
(0)

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