Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
luzhipeng committed Jun 28, 2019
1 parent 2dc3d94 commit 3b66227
Show file tree
Hide file tree
Showing 9 changed files with 248 additions and 2 deletions.
3 changes: 2 additions & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The data structures mainly includes:

## Top Problems Progress

- [Top 100 Liked Questions](https://leetcode.com/problemset/top-100-liked-questions/) (70 / 100)
- [Top 100 Liked Questions](https://leetcode.com/problemset/top-100-liked-questions/) (72 / 100)

- [Top Interview Questions](https://leetcode.com/problemset/top-interview-questions/) (92 / 145)

Expand Down Expand Up @@ -118,6 +118,7 @@ The data structures mainly includes:
- [0283.move-zeroes](./problems/283.move-zeroes.md)
- [0342.power-of-four](./problems/342.power-of-four.md)
- [0349.intersection-of-two-arrays](./problems/349.intersection-of-two-arrays.md)
- [0437.path-sum-iii](./problems/437.path-sum-iii.md) 🆕
- [0371.sum-of-two-integers](./problems/371.sum-of-two-integers.md)
- [0575.distribute-candies](./problems/575.distribute-candies.md)

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。

## Top题目进度

- [Top 100 Liked Questions](https://leetcode.com/problemset/top-100-liked-questions/) (70 / 100)
- [Top 100 Liked Questions](https://leetcode.com/problemset/top-100-liked-questions/) (72 / 100)

- [Top Interview Questions](https://leetcode.com/problemset/top-interview-questions/) (92 / 145)
## 传送门
Expand Down Expand Up @@ -118,6 +118,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [0283.move-zeroes](./problems/283.move-zeroes.md)
- [0342.power-of-four](./problems/342.power-of-four.md)
- [0349.intersection-of-two-arrays](./problems/349.intersection-of-two-arrays.md)
- [0437.path-sum-iii](./problems/437.path-sum-iii.md) 🆕
- [0371.sum-of-two-integers](./problems/371.sum-of-two-integers.md)
- [0575.distribute-candies](./problems/575.distribute-candies.md)

Expand Down
1 change: 1 addition & 0 deletions assets/drawio/437.path-sum-iii.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile modified="2019-06-28T08:13:53.640Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" etag="cftZSqvnzNecOcGb3rIg" version="10.8.2" type="device"><diagram id="h5GrOjgCf6RgwEEO3gBQ" name="第 1 页">7ZxNl6I4FIZ/jcvykARCWFofPb3pOXWmFtPdOwZSyhkUG2Or8+s7CAGSWEhR6tU+s6kiNyGQl4ck9yY4Ig/z7R95uJx9yWKejrATb0fkcYRxgJj8Wxh2pcFDTmmY5klcmlBjeEn+45VRFVsnMV9pBUWWpSJZ6sYoWyx4JDRbmOfZRi/2mqX6VZfhlFuGlyhMbevfSSxmpZVhv7F/5sl0pq6MaFDmzENVuGrJahbG2aZlIk8j8pBnmSiP5tsHnhbaKV3K8z69kVvfWM4Xos8J6V+7++9x/MRnn54n8aPzZfnn5K6q5WeYrg3hV2KnNJD1SLll4n4zSwR/WYZRkbORD1zaZmKeyhSSh1VlPBd8++ZdorrtkhmezbnId7JIdQJR1694YVVy04jvVaZZS3dlC6vHPa0rbhSRB5Uo7xAIWwJ5w/V5TdL0IUuzfH8eeWURjyJpX4k8+5e3cv5hniubdBJFsasriiiwpMSSVJmgmGPsuhRyLYU+IBAIdMjXoashhJLUsyTFV9XPgQtE7ZEAgSrkMkMhD1gh31YIFiHjHSMEWCB2+92Wc2WSBvZYCdtv1fOfa1FI9aMtiWyBFvGk8AVkKkrD1SqJdF34NhFf5bFTHX9r2R+3rYzHnUos5L1/VcWKxLd2TnPSPqXOGso0jy0nxXhesrnZOo94l1BlORHmUy6OzXjt59/z+eY8DUXyU7/dQw+9usJzlsiG1HgF+vvnUgObspXVSW1nx6gHGZNeFxkVlTJYFe0RrFv9ASptx+oCVILyBcoNdrE+WXDoMHCwo/sCVsd1bnBsh/N3B8ft2TExUMA8X+cCkYGAIQMws4s7N2C2+z0YMNQbMABcAkhcEDNwCQbigtxgTImPKWEuRchzjOmX6459OQdDAWZBELj+ZVmyAxUXYKmee9WJPnOvU490PQj0QAkMdAKJM5RAr5tAD5RAO65zW71Z31k5AR38HIOloYMfot0sUVCW7BDYRXuzMabv6dD2qWeeJ7LdPD89mV5PMn1QMpFBJh5Kpt9Npg9Kph16hBtnxxgYTNITTAoKJjbAJEPBZN1gMlAw7ZAv9Pox0fXxSDVHBYtP2iHcm1tBprqmFAFriu2YL/ASsqtmRFcjkR2AvLnFmMDALoDWFFuaHhiHATs7eIXs4BLwKrI5XvoOtER2zAR4Gdl4zXwGrZDt08N27ghfm0K2p/qRZWGYSYVS52pEPaGT9XsvJFeT/qMOGIINwSP9rQ3UlOz9QSu9IkaNis7sZGHbyboAmLCIgZKDqe6706G7EDDRvYJ68nEpcmzf8wLknJCDesv/0U0roGstmGEDGCMM0xsY1wDG7LPODAyxHevBwPQPNMJuW+mNGGw8EemI+Wakr3+g2+2KJ/oBA4wnkhNum7qhBWUVIzzOIAZlEBsMekMZZJ0MMgeUQQzB4Clp6js/b32GBkETMWgaOmiioJsmBEoTyHarq11UVq0/zqYLyqaxndT3h07onG42MSib17R9C3xZWS0qHUcTdi+OZ6DJhqKJutEkoGge2tdFU1F4C9m+FQ2j9Mc6Uxl3q/0X5BNZQFKwbTJHxSfiypFojMTnIeVO20SnxX+X+ONlKGZ3q/X8LkkSdXXZmvIGymLW+yL4VuhviO7FLLIFN1yeyhSmyXRRvGaS3ILv+yK8mkRhOqky5kkcp2+Fc/NsvYh5rL0WJ119cw98oFh/nX2Z74YP7c/6n4kLMoHNPsI/HxMy2fw2QtmtND8wQZ5+AQ==</diagram></mxfile>
1 change: 1 addition & 0 deletions assets/drawio/560.subarray-sum-equals-k.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile modified="2019-06-28T08:34:51.832Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" etag="KifvGym_ZoCTUZblt02z" version="10.8.2" type="device"><diagram id="xFxd8wiRep7FchxX0ach" name="第 1 页">5Vtbc6M2FP41fowHISDwmE3SbR863TY73e5Th4BimAByhby2++srgrjp4NTrAIJsHjLoAAK+852r5BW+TQ8fmb+NfqUhSVamER5W+G5lmh5yxf9CcCwFNjJKwYbFYSlCjeAh/pdIYXXZLg5J3rmQU5rweNsVBjTLSMA7Mp8xuu9e9kST7lO3/oYAwUPgJ1D6JQ55VEpd87qR/0ziTVQ9GTleeSb1q4vll+SRH9J9S4TvV/iWUcrLo/RwS5ICuwqX8r6fTpytX4yRjJ9zw+ffHr2/P/8Sbn//au6//PnxMQ3/uJKzfPOTXfeDc36sIGB0l4WkmMVY4Q/7KObkYesHxdm90LmQRTxNxAiJw6c4SW5pQtnLvfjJDUgQCHnOGX0mrTOPrm3ZxYTyDQjj5HDy01ANmCAaoSnh7CguqW5wJMaSZJYc7huN2VIUtZRVyXzJkU09cQOjOJBIfgeqJkDVXCCqtQ3OBFUMUMVLRHVmXLWGRnUAjPDMmGcDjAz9GM2MR84MeWTNjEfXACNLP0Yz45E7dOwcACN7ZjzyAEbPYvhyZDgALfHdvAtJN8BlNCNKNJQiP4k3mRgGAici5B8KFGORHN/IE2kchsVjenXQ1dITzXgrpF7f3zj3lVym/eZAIdZR1GWbaxsoDOEejZn2SBqr3qilMqAnkoU3RcXS4N/OVRSYTsEpIGLHvyTmL4OvxWDtWdX47tA+e3dsjz4RFosPLnR91yiDhKBGUlQhijKfbQh/DYF+lZ1pQowkPo+/dV+jT0vyCZ9oLF7wZIGATMU0c7pjAZF3tYsoZSI1J0ZImajEAUz0Qpr6s9/AI1iwjcwjtDasNpXQmDzSxQ814byYH+pE3sT0gJXnnOOBJCKyIBENw3EwHqqQtbvaNWD8tvqiwVjxG8FSdhwrnrvdAb98faHdqRNNbXewip44vDuaw7ut1X0PRyNvrfgKa2ImwV6Dt1QPXvwN5MEto18r2jw4bHe8ZvBB4ud5HJy0+VfxI4eY1yYvjkuLt+WosfdiUJn7+ZZdmsb/5hRziRCmao+XRojJM3fY/BmdMeiHZIw9EGNAUTA1Y2Ar7N36GK3pQ932eWv1B3yM2gEcmzGwMfhufYxexmCFMfhSH6OZMRXTX2NMk/WhM9ZUp0sKkdNVQp3ttTiAzb6sUI0Iwy38w/Zc5OdRKlD64XN4t8t0bMKe/KQpfMX0Afe+6CuIasfWQrMyjzaaqp8aDs3hd2eoaGrZraHi7OrGGRaesMO7FNbWGbY2NGFRBrsti0GzpykyLZow/VyOR8WGkk3o9qgYpmYLRlO338TD73TVh6Z2v4mXnDsBNHX7TTz96tHac5UFpHr8ntb11c22ptrCO3vfhzKR63XnGblMx3BVaByGzF2har/kYoWqE028YIzPSeMX0iIYcKOG11UK6skaJu0RYA2LNppa8CUjtTlqZdGm7qS/1VGjiQ3bgln7aIx5P9pX7f5S7YN2+tTah10w2zHW+e7RZ8w/XuW79Ir8s/OT/Op5/u7+jEzhbQ1811R229g9O/PqdP07vLsYNj+sLJXb/DoV3/8H</diagram></mxfile>
Binary file added assets/problems/437.path-sum-iii-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/problems/437.path-sum-iii-2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/problems/560.subarray-sum-equals-k.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
159 changes: 159 additions & 0 deletions problems/437.path-sum-iii.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
## 题目地址

https://leetcode.com/problems/path-sum-iii/description/

## 题目描述

```
You are given a binary tree in which each node contains an integer value.
Find the number of paths that sum to a given value.
The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
Example:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
Return 3. The paths that sum to 8 are:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
```

## 思路
这道题目是要我们求解出任何一个节点出发到子孙节点的路径中和为指定值。
注意这里,不一定是从根节点出发,也不一定在叶子节点结束。

一种简单的思路就是直接递归解决,空间复杂度O(n) 时间复杂度介于O(nlogn) 和 O(n^2),
具体代码:

```js
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
// the number of the paths starting from self
function helper(root, sum) {
if (root === null) return 0;
const l = helper(root.left, sum - root.val);
const r = helper(root.right, sum - root.val);

return l + r + (root.val === sum ? 1 : 0);
}
/**
* @param {TreeNode} root
* @param {number} sum
* @return {number}
*/
var pathSum = function(root, sum) {
// 空间复杂度O(n) 时间复杂度介于O(nlogn) 和 O(n^2)
// tag: dfs tree
if (root === null) return 0;
// the number of the paths starting from self
const self = helper(root, sum);
// we don't know the answer, so we just pass it down
const l = pathSum(root.left, sum);
// we don't know the answer, so we just pass it down
const r = pathSum(root.right, sum);

return self + l + r;
};

```


但是还有一种空间复杂度更加优秀的算法,利用hashmap来避免重复计算,时间复杂度和空间复杂度都是O(n)。
这种思路是`subarray-sum-equals-k`的升级版本,如果那道题目你可以O(n)解决,这道题目难度就不会很大,
只是将数组换成了二叉树。关于具体的思路可以看[这道题目](./560.subarray-sum-equals-k.md)


这里有一个不一样的地方,这里我说明一下,就是为什么要有`hashmap[acc] = hashmap[acc] - 1;`
原因很简单,就是我们DFS的时候,从底部往上回溯的时候,map的值应该也回溯。如果你对回溯法比较熟悉的话,
应该很容易理解,如果不熟悉可以参考[这道题目](./46.permutations.md), 这道题目就是通过`tempList.pop()`来完成的。

另外我画了一个图,相信看完你就明白了。

当我们执行到底部的时候:

![437.path-sum-iii](../assets/problems/437.path-sum-iii-1.jpg)

接着往上回溯:

![437.path-sum-iii-2](../assets/problems/437.path-sum-iii-2.jpg)

很容易看出,我们的hashmap不应该有第一张图的那个记录了,因此需要减去。


具体实现见下方代码区。

## 关键点解析

- 通过hashmap,以时间换空间
- 对于这种连续的元素求和问题,有一个共同的思路,可以参考[这道题目](./560.subarray-sum-equals-k.md)

## 代码

* 语言支持:JS

```js


/*
* @lc app=leetcode id=437 lang=javascript
*
* [437] Path Sum III
*/
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
function helper(root, acc, target, hashmap) {
// see also : https://leetcode.com/problems/subarray-sum-equals-k/

if (root === null) return 0;
let count = 0;
acc += root.val;
if (acc === target) count++;
if (hashmap[acc - target] !== void 0) {
count += hashmap[acc - target];
}
if (hashmap[acc] === void 0) {
hashmap[acc] = 1;
} else {
hashmap[acc] += 1;
}
const res =
count +
helper(root.left, acc, target, hashmap) +
helper(root.right, acc, target, hashmap);

// 这里要注意别忘记了
hashmap[acc] = hashmap[acc] - 1;

return res;
}

var pathSum = function(root, sum) {
// 时间复杂度和空间复杂度都是O(n)
const hashmap = {};
return helper(root, 0, sum, hashmap);
};
```
83 changes: 83 additions & 0 deletions problems/560.subarray-sum-equals-k.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@


## 题目地址
https://leetcode.com/problems/subarray-sum-equals-k/description/

## 题目描述
```
Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.
Example 1:
Input:nums = [1,1,1], k = 2
Output: 2
Note:
The length of the array is in range [1, 20,000].
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].
```
## 思路
符合直觉的做法是暴力求解所有的子数组,然后分别计算和,如果等于k,count就+1.这种做法的时间复杂度为O(n^2).

这里有一种更加巧妙的方法,我们可以借助额外的空间,使用hashmap来简化时间复杂度,这种算法的时间复杂度可以达到O(n).

我们维护一个hashmap,hashmap的key为累加值acc,value为累加值acc出现的次数。
我们迭代数组,然后不断更新acc和hashmap,如果acc 等于k,那么很明显应该+1. 如果hashmap[acc - k] 存在,
我们就把它加到结果中去即可。

语言比较难以解释,我画了一个图来演示nums = [1,2,3,3,0,3,4,2], k = 6的情况。

![560.subarray-sum-equals-k](../assets/problems/560.subarray-sum-equals-k.jpg)

如图,当访问到nums[3]的时候,hashmap如图所示,这个时候count为2.
其中之一是[1,2,3],这个好理解。还有一个是[3,3].

这个[3,3]正是我们通过hashmap[acc - k]即hashmap[9 - 6]得到的。

## 关键点解析

- 可以利用hashmap记录和的累加值来避免重复计算

## 代码
```js
/*
* @lc app=leetcode id=560 lang=javascript
*
* [560] Subarray Sum Equals K
*/
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var subarraySum = function(nums, k) {
const hashmap = {};
let acc = 0;
let count = 0;

for (let i = 0; i < nums.length; i++) {
acc += nums[i];

if (acc === k) count++;

if (hashmap[acc - k] !== void 0) {
count += hashmap[acc - k];
}

if (hashmap[acc] === void 0) {
hashmap[acc] = 1;
} else {
hashmap[acc] += 1;
}
}

return count;
};
```

## 扩展

这是一道类似的题目,但是会稍微复杂一点, 题目地址: [437.path-sum-iii](./437.path-sum-iii.md)




0 comments on commit 3b66227

Please sign in to comment.