Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/azl397985856/leetcode
Browse files Browse the repository at this point in the history
  • Loading branch information
lucifer committed Apr 16, 2020
2 parents d971646 + f04b4f9 commit fa2e7e4
Show file tree
Hide file tree
Showing 14 changed files with 596 additions and 8 deletions.
9 changes: 8 additions & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ The data structures mainly includes:
#### Easy

- [0001.TwoSum](./problems/1.TwoSum.md)🆕
- [0020.Valid Parentheses](./problems/20.validParentheses.md)
- [0021.MergeTwoSortedLists](./problems/21.MergeTwoSortedLists.md) 🆕
- [0026.remove-duplicates-from-sorted-array](./problems/26.remove-duplicates-from-sorted-array.md)
- [0053.maximum-sum-subarray](./problems/53.maximum-sum-subarray-en.md) 🆕
- [0088.merge-sorted-array](./problems/88.merge-sorted-array.md)
Expand All @@ -136,9 +138,10 @@ The data structures mainly includes:
- [0263.ugly-number](./problems/263.ugly-number.md)
- [0283.move-zeroes](./problems/283.move-zeroes.md)
- [0342.power-of-four](./problems/342.power-of-four.md)
- [0371.sum-of-two-integers](./problems/371.sum-of-two-integers.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)
- [0455.AssignCookies](./problems/455.AssignCookies.md) 🆕
- [0501.find-mode-in-binary-search-tree](./problems/501.Find-Mode-in-Binary-Search-Tree.md) 🆕
- [0575.distribute-candies](./problems/575.distribute-candies.md)

Expand All @@ -149,7 +152,9 @@ The data structures mainly includes:
- [0005.longest-palindromic-substring](./problems/5.longest-palindromic-substring.md)
- [0011.container-with-most-water](./problems/11.container-with-most-water.md)
- [0015.3-sum](./problems/15.3-sum.md)
- [0017.Letter-Combinations-of-a-Phone-Number](./problems/17.Letter-Combinations-of-a-Phone-Number.md) 🆕
- [0019. Remove Nth Node From End of List](./problems/19.removeNthNodeFromEndofList.md)
- [0022.GenerateParentheses](./problems/22.GenerateParentheses.md) 🆕
- [0024. Swap Nodes In Pairs](./problems/24.swapNodesInPairs.md)
- [0029.divide-two-integers](./problems/29.divide-two-integers.md)
- [0031.next-permutation](./problems/31.next-permutation.md)
Expand All @@ -175,6 +180,7 @@ The data structures mainly includes:
- [0098.validate-binary-search-tree](./problems/98.validate-binary-search-tree.md)
- [0102.binary-tree-level-order-traversal](./problems/102.binary-tree-level-order-traversal.md)
- [0103.binary-tree-zigzag-level-order-traversal](./problems/103.binary-tree-zigzag-level-order-traversal.md)
- [105.Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal.md](./problems/105.Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal.md)
- [0113.path-sum-ii](./problems/113.path-sum-ii.md)
- [0129.sum-root-to-leaf-numbers](./problems/129.sum-root-to-leaf-numbers.md)
- [0130.surrounded-regions](./problems/130.surrounded-regions.md)
Expand Down Expand Up @@ -226,6 +232,7 @@ The data structures mainly includes:
- [0025.reverse-nodes-in-k-group](./problems/25.reverse-nodes-in-k-groups-en.md) 🆕
- [0032.longest-valid-parentheses](./problems/32.longest-valid-parentheses.md) 🆕
- [0042.trapping-rain-water](./problems/42.trapping-rain-water.md)
- [0052.N-Queens-II](./problems/52.N-Queens-II.md) 🆕
- [0124.binary-tree-maximum-path-sum](./problems/124.binary-tree-maximum-path-sum.md)
- [0128.longest-consecutive-sequence](./problems/128.longest-consecutive-sequence.md)
- [0145.binary-tree-postorder-traversal](./problems/145.binary-tree-postorder-traversal.md)
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ leetcode 题解,记录自己的 leetcode 解题之路。
#### 简单难度

- [0001.TwoSum](./problems/1.TwoSum.md) 🆕
- [0020.Valid Parentheses](./problems/20.validParentheses.md)
- [0021.MergeTwoSortedLists](./problems/21.MergeTwoSortedLists.md) 🆕
- [0026.remove-duplicates-from-sorted-array](./problems/26.remove-duplicates-from-sorted-array.md)
- [0053.maximum-sum-subarray](./problems/53.maximum-sum-subarray-cn.md) 🆕
- [0088.merge-sorted-array](./problems/88.merge-sorted-array.md)
Expand All @@ -149,8 +151,9 @@ 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)
- [0437.path-sum-iii](./problems/437.path-sum-iii.md) 🆕
- [0455.AssignCookies](./problems/455.AssignCookies.md) 🆕
- [0501.find-mode-in-binary-search-tree](./problems/501.Find-Mode-in-Binary-Search-Tree.md)🆕
- [0575.distribute-candies](./problems/575.distribute-candies.md)
- [0874.walking-robot-simulation](./problems/874.walking-robot-simulation.md) 🆕
Expand All @@ -164,7 +167,9 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [0005.longest-palindromic-substring](./problems/5.longest-palindromic-substring.md)
- [0011.container-with-most-water](./problems/11.container-with-most-water.md)
- [0015.3-sum](./problems/15.3-sum.md)
- [0017.Letter-Combinations-of-a-Phone-Number](./problems/17.Letter-Combinations-of-a-Phone-Number.md) 🆕
- [0019. Remove Nth Node From End of List](./problems/19.removeNthNodeFromEndofList.md)
- [0022.GenerateParentheses](./problems/22.GenerateParentheses.md) 🆕
- [0024. Swap Nodes In Pairs](./problems/24.swapNodesInPairs.md)
- [0029.divide-two-integers](./problems/29.divide-two-integers.md)
- [0031.next-permutation](./problems/31.next-permutation.md)
Expand Down Expand Up @@ -195,6 +200,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [0098.validate-binary-search-tree](./problems/98.validate-binary-search-tree.md)
- [0102.binary-tree-level-order-traversal](./problems/102.binary-tree-level-order-traversal.md)
- [0103.binary-tree-zigzag-level-order-traversal](./problems/103.binary-tree-zigzag-level-order-traversal.md)
- [105.Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal.md](./problems/105.Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal.md)
- [0113.path-sum-ii](./problems/113.path-sum-ii.md)
- [0129.sum-root-to-leaf-numbers](./problems/129.sum-root-to-leaf-numbers.md)
- [0130.surrounded-regions](./problems/130.surrounded-regions.md)
Expand Down Expand Up @@ -266,6 +272,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [0030.substring-with-concatenation-of-all-words](./problems/30.substring-with-concatenation-of-all-words.md)
- [0032.longest-valid-parentheses](./problems/32.longest-valid-parentheses.md)
- [0042.trapping-rain-water](./problems/42.trapping-rain-water.md)
- [0052.N-Queens-II](./problems/52.N-Queens-II.md) 🆕
- [0084.largest-rectangle-in-histogram](./problems/84.largest-rectangle-in-histogram.md) 🆕
- [0085.maximal-rectangle](./problems/85.maximal-rectangle.md)
- [0124.binary-tree-maximum-path-sum](./problems/124.binary-tree-maximum-path-sum.md)
Expand Down
Binary file added assets/problems/105.index_explain.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions problems/1.TwoSum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## 题目地址
https://leetcode-cn.com/problems/two-sum

## 题目描述
```
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
```
## 思路
最容易想到的就是暴力枚举,我们可以利用两层 for 循环来遍历每个元素,并查找满足条件的目标元素。不过这样时间复杂度为 O(N^2),空间复杂度为 O(1),时间复杂度较高,我们要想办法进行优化。我们可以增加一个 Map 记录已经遍历过的数字及其对应的索引值。这样当遍历一个新数字的时候去 Map 里查询,target 与该数的差值是否已经在前面的数字中出现过。如果出现过,那么已经得出答案,就不必再往下执行了。

## 关键点

- 求和转换为求差
- 借助 Map 结构将数组中每个元素及其索引相互对应
- 以空间换时间,将查找时间从 O(N) 降低到 O(1)

## 代码
* 语言支持:JS

```js
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
const twoSum = function (nums, target) {
const map = new Map();
for (let i = 0; i < nums.length; i++) {
const diff = target - nums[i];
if (map.has(diff)) {
return [map.get(diff), i];
}
map.set(nums[i], i);
}
}
```

***复杂度分析***

- 时间复杂度:O(N)
- 空间复杂度:O(N)
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
## 问题地址/Problem URL

https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

## 问题介绍/Problem Description

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

For example, given

```java
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
```

Return the following binary tree:

```bash
3
/ \
9 20
/ \
15 7
```

## 思路/Thinking Path

目标是构造二叉树。

构造二叉树需要根的值、左子树和右子树。

此问题可被抽象为:从前序遍历和中序遍历中找到根节点、左子树和右子树。

先找根:
由前序遍历的性质,第`0`个节点为当前树的根节点。
再找左右子树:
在中序遍历中找到这个根节点,设其下标为`i`。由中序遍历的性质,`0 ~ i-1` 是左子树的中序遍历,`i+1 ~ inorder.length-1`是右子树的中序遍历。

然后递归求解,终止条件是左右子树为`null`

We are going to construct a binary tree from its preorder and inorder traversal.

To build a binary tree, it requires us to creact a new `TreeNode` as the root with filling in the root value. And then, find its left child and right child recursively until the left or right child is `null`.

Now this problem is abstracted as how to find the root node, left child and right child from the preorder traversal and inorder traversal.

In preorder traversal, the first node (`preorder[0]`) is the root of current binary tree. In inorder traversal, find the location of this root which is `i`. The left sub-tree is `0 to i-1` and the right sub-tree is `i+1 to inorder.length-1` in inorder traversal.

Then applying the previous operation to the left and right sub-trees.

## 关键解析/Key Points

如何在前序遍历的数组里找到左右子树的:
- 根据前序遍历的定义可知,每个当前数组的第一个元素就是当前子树的根节点的值
- 在中序遍历数组中找到这个值,设其下标为`inRoot`
- 当前中序遍历数组的起点`inStart``inRoot`之间就是左子树,其长度`leftChldLen``inRoot-inStart`
- 当前中序遍历数组的终点`inEnd``inRoot`之间就是右子树
- 前序遍历和中序遍历中左子树的长度是相等的,所以在前序遍历数组中,根节点下标`preStart`往后数`leftChldLen`即为左子树的最后一个节点,其下标为`preStart+leftChldLen`,右子树的第一个节点下标为`preStart+leftChldLen+1`

**PLEASE READ THE CODE BEFORE READING THIS PART**

If you can't figure out how to get the index of the left and right child, please read this.

- index of current node in preorder array is preStart(or whatever your call it), it's the root of a subtree.
- according to the properties of preoder traversal, all right sub-tree nodes are behine all left sub-tree nodes. The length of left sub-tree can help us to divide left and right sub-trees.
- the length of left sub-tree can be find in the inorder traversal. The location of current node is `inRoot`(or whatever your call it). The start index of current inorder array is `inStart`(or whatever your call it). So, the lenght of the left sub-tree is `leftChldLen = inRoot - inStart`.

![explain](../assets/problems/105.index_explain.jpg)

## 代码/Code

- Java

```java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder.length != inorder.length) return null;

HashMap<Integer, Integer> map = new HashMap<> ();

for (int i=0; i<inorder.length; i++) {
map.put(inorder[i], i);
}

return helper(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1, map);
}

public TreeNode helper(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd, HashMap<Integer, Integer> map) {
if (preStart>preEnd || inStart>inEnd) return null;

TreeNode root = new TreeNode(preorder[prestart]);
int inRoot = map.get(preorder[preStart]);
int leftChldLen = inRoot - inStart;

root.left = helper(preorder, preStart+1, preStart+leftChldLen, inorder, inStart, inRoot-1, map);
root.left = helper(preorder, preStart+leftChldLen+1, preEnd, inorder, inRoot+1, inEnd, map);

return root;
}
}
```
34 changes: 34 additions & 0 deletions problems/124.binary-tree-maximum-path-sum.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ Output: 42

## 代码

代码支持:JavaScript,Java

- JavaScript

```js


Expand Down Expand Up @@ -116,5 +120,35 @@ var maxPathSum = function(root) {
};
```

- Java

```java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int ans;
public int maxPathSum(TreeNode root) {
ans = Integer.MIN_VALUE;
helper(root); // recursion
return ans;
}

public int helper(TreeNode root) {
if (root == null) return 0;
int leftMax = Math.max(0, helper(root.left)); // find the max sub-path sum in left sub-tree
int rightMax = Math.max(0, helper(root.right)); // find the max sub-path sum in right sub-tree
ans = Math.max(ans, leftMax+rightMax+root.val); // find the max path sum at current node
return max(leftMax, rightMax) + root.val; // according to the definition of path, the return value of current node can only be that the sum of current node value plus either left or right max path sum.
}
}
```

## 相关题目
- [113.path-sum-ii](./113.path-sum-ii.md)
77 changes: 77 additions & 0 deletions problems/17.Letter-Combinations-of-a-Phone-Number.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
## 题目地址
https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number

## 题目描述
```
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
```

## 思路
使用回溯法进行求解,回溯是一种通过穷举所有可能情况来找到所有解的算法。如果一个候选解最后被发现并不是可行解,回溯算法会舍弃它,并在前面的一些步骤做出一些修改,并重新尝试找到可行解。究其本质,其实就是枚举。

如果没有更多的数字需要被输入,说明当前的组合已经产生。

如果还有数字需要被输入:
- 遍历下一个数字所对应的所有映射的字母
- 将当前的字母添加到组合最后,也就是 str + tmp[r]

## 关键点
利用回溯思想解题,在for循环中调用递归。

## 代码
* 语言支持:JS

```js
/**
* @param {string} digits
* @return {string[]}
*/
const letterCombinations = function (digits) {
if (!digits) {
return [];
}
const len = digits.length;
const map = new Map();
map.set('2', 'abc');
map.set('3', 'def');
map.set('4', 'ghi');
map.set('5', 'jkl');
map.set('6', 'mno');
map.set('7', 'pqrs');
map.set('8', 'tuv');
map.set('9', 'wxyz');
const result = [];

function generate(i, str) {
if (i == len) {
result.push(str);
return;
}
const tmp = map.get(digits[i]);
for (let r = 0; r < tmp.length; r++) {
generate(i + 1, str + tmp[r]);
}
}
generate(0, '');
return result;
};
```

***复杂度分析***

N + M 是输入数字的总数

- 时间复杂度:O(3^N * 4^M)
- 空间复杂度:O(3^N * 4^M)

Loading

0 comments on commit fa2e7e4

Please sign in to comment.