Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
luzhipeng committed Apr 28, 2019
1 parent badd4e0 commit 0782afa
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 128 deletions.
72 changes: 0 additions & 72 deletions 236.lowest-common-ancestor-of-a-binary-tree.js

This file was deleted.

56 changes: 0 additions & 56 deletions 238.product-of-array-except-self.js

This file was deleted.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [201.bitwise-and-of-numbers-range](./problems/201.bitwise-and-of-numbers-range.md)
- 🆕 [208.implement-trie-prefix-tree](./problems/208.implement-trie-prefix-tree.md)
- 🖊 [209.minimum-size-subarray-sum](./problems/209.minimum-size-subarray-sum.md)
- 🆕 [236.lowest-common-ancestor-of-a-binary-tree](./problems/236.lowest-common-ancestor-of-a-binary-tree.md)
- 🆕 [238.product-of-array-except-self](./problems/238.product-of-array-except-self.md)
- [240.search-a-2-d-matrix-ii](./problems/240.search-a-2-d-matrix-ii.md)
- 🖊 [279.perfect-squares](./problems/279.perfect-squares.md)
- [322.coin-change](./problems/322.coin-change.md)
Expand Down
1 change: 1 addition & 0 deletions assets/drawio/238.product-of-array-except-self.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile modified="2019-04-28T06:28:16.663Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36" etag="UbIXGt9flWtJSxW6MS5P" version="10.6.5" type="device"><diagram id="P2b4O3X3tyGLODaJQv60" name="第 1 页">7Ztdb5swFIZ/jW8mrcI2EHK5pGS72LSPTpp2NRFwAhpgBk6T7NfPBpMAplOqkeBqVK0Cx8aY9znY59gpwMvk8Db3svADDUgMkBEcAL4HCEE8d/iHsBwry8yGlWGbR4GsdDY8RL+JNBrSuosCUrQqMkpjFmVto0/TlPisZfPynO7b1TY0bt8187ZEMTz4Xqxav0UBCyurg2Zn+zsSbcP6ztCeVyWJV1eWT1KEXkD3DRN2AV7mlLLqKDksSSzEq3Wprls9UXrqWE5SdskFfv76+8eN+SXE6dcjXn8+wsh6LVt59OJd+4ELdqwlyOkuDYhoxQB4sQ8jRh4yzxelew6d20KWxPwM8kPZHskZOTzZUXh6fO43hCaE5Udepb7AlIoda03l+f4MwJKmsKF9bfMk8u2p5bMq/EAK8wyRsCISGl+kuWYimYpIeHSRkG6eZCkimeOLpJsn2YpIikYZjVJGcveRP2MhpTiNr0K2wCvCk4YNvQqW059kSWOac0tKU97gIvbWJP5Ei4hFNOVmn4jGeYHQNeJzwftOhTVljCaNCm/iaCsKGBV8PHl2aod3LRM9Tw5bMUveJYXvkbuAZDnxPUaCu4wWvOaPcsLi9TdRHNd9BAgbxmK5QgONG5bVom2psNEtYc8m2E/ADiJ+gezDnhRsGP7YaPPHPW/7TR3A0TACMSHWa0ic6yiSrZlI9f3bKhmv+N/48Zqlm0vB3tC/Vqv8HD+As7TzMaThm9hNmPom9duq9BIypvFVegkp0/gqvYScaXyV1KSpHs0BsmMRPG4ofzaxUFaHmvavHa2iSrzZmB6ymyZ7Kz4Rb8D2EiFgui6yskRMC2XDZt0y73HVeHXR6HS64dv4dNQsB/4jGQmgnqc1BWHrBqI32zgFPQMA0RNEN/ocH0RvRtONPi8EgvlPPxCoLRDd3gykpgPpLikUofgjswtWWZqLGtKkLJR011OSKAjEbXrlbwMSLFtrJvO5UdvlHhIyhiHldFZHkaWAMntAoauBUmPrCVQPKGSPDUoN7y8bztbWzFCHs5wUlw5m/x16bOv2kqpJy8T+NuzHf+8H3b+Cf4PZ3C7Qel9DutgAuJGh1/4VGnQDa6Ldoa3ZbiVS88eJ9mC0u3uTo9NWk9SJdkX7OpvT3S8njL45jdUtxckDrukB3el9fA9Q10UmD7iqB2g3BiDVA1wLOPzXAa4JFgvguMLyhh+bwJ0DBwLnvqzjAsdW3EWPFK3lk428DNpq/jZbGcZqNdAkD9t8oaPyhfiWCRtWV9RKeHZJsQF4YYCFOwF+JmDTuB5gfnr+An1Z1vg3BOz+AQ==</diagram></mxfile>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
149 changes: 149 additions & 0 deletions problems/236.lowest-common-ancestor-of-a-binary-tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
## 题目地址

https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/

## 题目描述

```
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]
```
![236.lowest-common-ancestor-of-a-binary-tree](../assets/problems/236.lowest-common-ancestor-of-a-binary-tree-1.png)

```
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
Note:
All of the nodes' values will be unique.
p and q are different and both values will exist in the binary tree.
```

## 思路

这道题目是求解二叉树中,两个给定节点的最近的公共祖先。是一道非常经典的二叉树题目。

我们之前说过树是一种递归的数据结构,因此使用递归方法解决二叉树问题从写法上来看是最简单的,这道题目也不例外。

用递归的思路去思考树是一种非常重要的能力。


如果大家这样去思考的话,问题就会得到简化,我们的目标就是分别在左右子树进行查找p和q。 如果p没有在左子树,那么它一定在右子树(题目限定p一定在树中),
反之亦然。

对于具体的代码而言就是,我们假设这个树就一个结构,然后尝试去解决,然后在适当地方去递归自身即可。 如下图所示:

![236.lowest-common-ancestor-of-a-binary-tree-2](../assets/problems/236.lowest-common-ancestor-of-a-binary-tree-2.png)

我们来看下核心代码:

```js
// 如果我们找到了p,直接进行返回,那如果下面就是q呢? 其实这没有影响,但是还是要多考虑一下
if (!root || root === p || root === q) return root;
const left = lowestCommonAncestor(root.left, p, q); // 去左边找,我们期望返回找到的节点
const right = lowestCommonAncestor(root.right, p, q);// 去右边找,我们期望返回找到的节点
if (!left) return right; // 左子树找不到,返回右子树
if (!right) return left; // 右子树找不到,返回左子树
return root; // 左右子树分别有一个,则返回root

```

> 如果没有明白的话,请多花时间消化一下
## 关键点解析

- 用递归的思路去思考树

## 代码

```js


/*
* @lc app=leetcode id=236 lang=javascript
*
* [236] Lowest Common Ancestor of a Binary Tree
*
* https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/
*
* algorithms
* Medium (35.63%)
* Total Accepted: 267.3K
* Total Submissions: 729.2K
* Testcase Example: '[3,5,1,6,2,0,8,null,null,7,4]\n5\n1'
*
* Given a binary tree, find the lowest common ancestor (LCA) of two given
* nodes in the tree.
*
* According to the definition of LCA on Wikipedia: “The lowest common ancestor
* is defined between two nodes p and q as the lowest node in T that has both p
* and q as descendants (where we allow a node to be a descendant of itself).”
*
* Given the following binary tree:  root = [3,5,1,6,2,0,8,null,null,7,4]
*
*
*
* Example 1:
*
*
* Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
* Output: 3
* Explanation: The LCA of nodes 5 and 1 is 3.
*
*
* Example 2:
*
*
* Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
* Output: 5
* Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant
* of itself according to the LCA definition.
*
*
*
*
* Note:
*
*
* All of the nodes' values will be unique.
* p and q are different and both values will exist in the binary tree.
*
*
*/
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {TreeNode} p
* @param {TreeNode} q
* @return {TreeNode}
*/
var lowestCommonAncestor = function(root, p, q) {
if (!root || root === p || root === q) return root;
const left = lowestCommonAncestor(root.left, p, q);
const right = lowestCommonAncestor(root.right, p, q);
if (!left) return right; // 左子树找不到,返回右子树
if (!right) return left; // 右子树找不到,返回左子树
return root; // 左右子树分别有一个,则返回root
};
```

102 changes: 102 additions & 0 deletions problems/238.product-of-array-except-self.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
## 题目地址

https://leetcode.com/problems/product-of-array-except-self/description/

## 题目描述

```
Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].
Example:
Input: [1,2,3,4]
Output: [24,12,8,6]
Note: Please solve it without division and in O(n).
Follow up:
Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)
```

## 思路

这道题的意思是给定一个数组,返回一个新的数组,这个数组每一项都是其他项的乘积。
符合直觉的思路是两层循环,时间复杂度是O(n),但是题目要求`Please solve it without division and in O(n)`

因此我们需要换一种思路,由于输出的每一项都需要用到别的元素,因此一次遍历是绝对不行的。
考虑我们先进行一次遍历, 然后维护一个数组,第i项代表前i个元素(不包括i)的乘积。
然后我们反向遍历一次,然后维护另一个数组,同样是第i项代表前i个元素(不包括i)的乘积。

![238.product-of-array-except-self](../assets/problems/238.product-of-array-except-self.png)

有意思的是第一个数组和第二个数组的反转(reverse)做乘法(有点像向量运算)就是我们想要的运算。

其实我们进一步观察,我们不需要真的创建第二个数组(第二个数组只是做中间运算使用),而是直接修改第一个数组即可。

## 关键点解析

- 两次遍历, 一次正向,一次反向。
- 维护一个数组,第i项代表前i个元素(不包括i)的乘积

## 代码

```js

/*
* @lc app=leetcode id=238 lang=javascript
*
* [238] Product of Array Except Self
*
* https://leetcode.com/problems/product-of-array-except-self/description/
*
* algorithms
* Medium (53.97%)
* Total Accepted: 246.5K
* Total Submissions: 451.4K
* Testcase Example: '[1,2,3,4]'
*
* Given an array nums of n integers where n > 1,  return an array output such
* that output[i] is equal to the product of all the elements of nums except
* nums[i].
*
* Example:
*
*
* Input: [1,2,3,4]
* Output: [24,12,8,6]
*
*
* Note: Please solve it without division and in O(n).
*
* Follow up:
* Could you solve it with constant space complexity? (The output array does
* not count as extra space for the purpose of space complexity analysis.)
*
*/
/**
* @param {number[]} nums
* @return {number[]}
*/
var productExceptSelf = function(nums) {
const ret = [];

for (let i = 0, temp = 1; i < nums.length; i++) {
ret[i] = temp;
temp *= nums[i];
}
// 此时ret[i]存放的是前i个元素相乘的结果(不包含第i个)

// 如果没有上面的循环的话,
// ret经过下面的循环会变成ret[i]存放的是后i个元素相乘的结果(不包含第i个)

// 我们的目标是ret[i]存放的所有数字相乘的结果(不包含第i个)

// 因此我们只需要对于上述的循环产生的ret[i]基础上运算即可
for (let i = nums.length - 1, temp = 1; i >= 0; i--) {
ret[i] *= temp;
temp *= nums[i];
}
return ret;
};
```

0 comments on commit 0782afa

Please sign in to comment.