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 83fc7a6 commit aac59ff
Show file tree
Hide file tree
Showing 14 changed files with 170 additions and 65 deletions.
61 changes: 0 additions & 61 deletions 152.maximum-product-subarray.js

This file was deleted.

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

- 第四部分是计划, 这里会记录将来要加入到以上三个部分内容

> 只有熟练掌握基础的数据结构与算法,才能对复杂问题迎刃有余
> 只有熟练掌握基础的数据结构与算法,才能对复杂问题迎刃有余
## 食用指南

Expand Down Expand Up @@ -115,6 +115,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [139.word-break](./problems/139.word-breakmd)
- [144.binary-tree-preorder-traversal](./problems/144.binary-tree-preorder-traversal.md)
- 🖊 [150.evaluate-reverse-polish-notation](./problems/150.evaluate-reverse-polish-notation.md)
- 🆕 [152.maximum-product-subarray](./problems/152.maximum-product-subarray.md)
- [199.binary-tree-right-side-view](./problems/199.binary-tree-right-side-view.md)
- [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)
Expand All @@ -132,6 +133,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [900.rle-iterator](./problems/900.rle-iterator.md)

#### 困难难度
- 🆕 [23.merge-k-sorted-lists](./problems/23.merge-k-sorted-lists.md)
- 🆕 [42.trapping-rain-water](./problems/42.trapping-rain-water.md)
- 🆕 [128.longest-consecutive-sequence](./problems/128.longest-consecutive-sequence.md)
- [145.binary-tree-postorder-traversal](./problems/145.binary-tree-postorder-traversal.md)
Expand Down
Binary file added assets/problems/152.maximum-product-subarray.png
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/23.merge-k-sorted-lists.gif
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.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
111 changes: 111 additions & 0 deletions problems/152.maximum-product-subarray.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
## 题目地址

https://leetcode.com/problems/maximum-product-subarray/description/

## 题目描述

```
Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.
Example 1:
Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:
Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
```

## 思路

> 这道题目的通过率非常低
这道题目要我们求解连续的 n 个数中乘积最大的积是多少。这里提到了连续,笔者首先
想到的就是滑动窗口,但是这里比较特殊,我们不能仅仅维护一个最大值,因此最小值(比如-20)乘以一个比较小的数(比如-10)
可能就会很大。 因此这种思路并不方便。

首先来暴力求解,我们使用两层循环来枚举所有可能项,这种解法的时间复杂度是O(n^2), 代码如下:

```js
var maxProduct = function(nums) {
let max = nums[0];
let temp = null;
for (let i = 0; i < nums.length; i++) {
temp = nums[i];
max = Math.max(temp, max);
for (let j = i + 1; j < nums.length; j++) {
temp *= nums[j];
max = Math.max(temp, max);
}
}

return max;
};
```

因此我们需要同时记录乘积最大值和乘积最小值,然后比较元素和这两个的乘积,去不断更新最大值。

![152.maximum-product-subarray](../assets/problems/152.maximum-product-subarray.png)

这种思路的解法由于只需要遍历依次,其时间复杂度是O(n),代码见下方代码区。
## 关键点

- 同时记录乘积最大值和乘积最小值

## 代码

```js
/*
* @lc app=leetcode id=152 lang=javascript
*
* [152] Maximum Product Subarray
*
* https://leetcode.com/problems/maximum-product-subarray/description/
*
* algorithms
* Medium (28.61%)
* Total Accepted: 202.8K
* Total Submissions: 700K
* Testcase Example: '[2,3,-2,4]'
*
* Given an integer array nums, find the contiguous subarray within an array
* (containing at least one number) which has the largest product.
*
* Example 1:
*
*
* Input: [2,3,-2,4]
* Output: 6
* Explanation: [2,3] has the largest product 6.
*
*
* Example 2:
*
*
* Input: [-2,0,-1]
* Output: 0
* Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
*
*/
/**
* @param {number[]} nums
* @return {number}
*/
var maxProduct = function(nums) {
let max = nums[0];
let min = nums[0];
let res = nums[0];

for (let i = 1; i < nums.length; i++) {
let tmp = min;
min = Math.min(nums[i], Math.min(max * nums[i], min * nums[i])); // 取最小
max = Math.max(nums[i], Math.max(max * nums[i], tmp * nums[i])); /// 取最大
res = Math.max(res, max);
}
return res;
};
```
53 changes: 51 additions & 2 deletions 23.merge-k-sorted-lists.js → problems/23.merge-k-sorted-lists.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
## 题目地址
https://leetcode.com/problems/merge-k-sorted-lists/description

## 题目描述

```
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
```

## 思路

这道题目是合并k个已排序的链表,号称leetcode目前`最难`的链表题。 和之前我们解决的[88.merge-sorted-array](./88.merge-sorted-array.md)很像。
他们有两点区别:

1. 这道题的数据结构是链表,那道是数组。这个其实不复杂,毕竟都是线性的数据结构。

2. 这道题需要合并k个元素,那道则只需要合并两个。这个是两题的关键差别,也是这道题难度为`hard`的原因。

因此我们可以看出,这道题目是`88.merge-sorted-array`的进阶版本。其实思路也有点像,我们来具体分析下第二条。
如果你熟悉合并排序的话,你会发现它就是`合并排序的一部分`

具体我们可以来看一个动画

![23.merge-k-sorted-lists](../assets/problems/23.merge-k-sorted-lists.gif)

(动画来自 https://zhuanlan.zhihu.com/p/61796021)
## 关键点解析

- 分治
- 合并排序(merge sort)

## 代码
```js
/*
* @lc app=leetcode id=23 lang=javascript
*
Expand Down Expand Up @@ -30,8 +74,8 @@
function mergeTwoLists(l1, l2) {
const dummyHead = {};
let current = dummyHead;
// 1 -> 3 -> 5
// 2 -> 4 -> 6
// l1: 1 -> 3 -> 5
// l2: 2 -> 4 -> 6
while (l1 !== null && l2 !== null) {
if (l1.val < l2.val) {
current.next = l1; // 把小的添加到结果链表
Expand Down Expand Up @@ -83,3 +127,8 @@ var mergeKLists = function(lists) {

return mergeTwoLists(mergeKLists(l1), mergeKLists(l2));
};
```

## 相关题目

-[88.merge-sorted-array](./88.merge-sorted-array.md)
6 changes: 5 additions & 1 deletion thinkings/binary-tree-traversal.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ BFS 的关键点在于如何记录每一层次是否遍历完成, 我们可以

其实从宏观上表现为:`自顶向下依次访问左侧链,然后自底向上依次访问右侧链`
如果从这个角度出发去写的话,算法就不一样了。从上向下我们可以直接递归访问即可,从下向上我们只需要借助栈也可以轻易做到。
整个过程大概是这样:

![binary-tree-traversal-preorder](../assets/thinkings/binary-tree-traversal-preorder.png)

这种思路解题有点像我总结过的一个解题思路`backtrack` - 回溯法。这种思路有一个好处就是
可以`统一三种遍历的思路`.
可以`统一三种遍历的思路`. 这个很重要,如果不了解的朋友,希望能够记住这一点。

## 中序遍历

Expand Down

0 comments on commit aac59ff

Please sign in to comment.