diff --git a/152.maximum-product-subarray.js b/152.maximum-product-subarray.js deleted file mode 100644 index 8f91af43b..000000000 --- a/152.maximum-product-subarray.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * @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 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; - 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; -}; diff --git a/README.md b/README.md index 1a1a38d6e..e9edc7427 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。 - 第四部分是计划, 这里会记录将来要加入到以上三个部分内容 -> 只有熟练掌握基础的数据结构与算法,才能对复杂问题迎刃有余 +> 只有熟练掌握基础的数据结构与算法,才能对复杂问题迎刃有余。 ## 食用指南 @@ -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) @@ -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) diff --git a/assets/problems/152.maximum-product-subarray.png b/assets/problems/152.maximum-product-subarray.png new file mode 100644 index 000000000..fc8d81cd5 Binary files /dev/null and b/assets/problems/152.maximum-product-subarray.png differ diff --git a/assets/problems/23.merge-k-sorted-lists.gif b/assets/problems/23.merge-k-sorted-lists.gif new file mode 100644 index 000000000..c78cf9494 Binary files /dev/null and b/assets/problems/23.merge-k-sorted-lists.gif differ diff --git a/assets/thinkings/binary-tree-traversal-preorder.png b/assets/thinkings/binary-tree-traversal-preorder.png new file mode 100644 index 000000000..75f543f79 Binary files /dev/null and b/assets/thinkings/binary-tree-traversal-preorder.png differ diff --git a/189.rotate-array.js b/backlog/189.rotate-array.js similarity index 100% rename from 189.rotate-array.js rename to backlog/189.rotate-array.js diff --git a/217.contains-duplicate.js b/backlog/217.contains-duplicate.js similarity index 100% rename from 217.contains-duplicate.js rename to backlog/217.contains-duplicate.js diff --git a/326.power-of-three.js b/backlog/326.power-of-three.js similarity index 100% rename from 326.power-of-three.js rename to backlog/326.power-of-three.js diff --git a/344.reverse-string.js b/backlog/344.reverse-string.js similarity index 100% rename from 344.reverse-string.js rename to backlog/344.reverse-string.js diff --git a/350.intersection-of-two-arrays-ii.js b/backlog/350.intersection-of-two-arrays-ii.js similarity index 100% rename from 350.intersection-of-two-arrays-ii.js rename to backlog/350.intersection-of-two-arrays-ii.js diff --git a/387.first-unique-character-in-a-string.js b/backlog/387.first-unique-character-in-a-string.js similarity index 100% rename from 387.first-unique-character-in-a-string.js rename to backlog/387.first-unique-character-in-a-string.js diff --git a/problems/152.maximum-product-subarray.md b/problems/152.maximum-product-subarray.md new file mode 100644 index 000000000..3aee557ef --- /dev/null +++ b/problems/152.maximum-product-subarray.md @@ -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; +}; +``` diff --git a/23.merge-k-sorted-lists.js b/problems/23.merge-k-sorted-lists.md similarity index 56% rename from 23.merge-k-sorted-lists.js rename to problems/23.merge-k-sorted-lists.md index 0a0f40f6e..e24529561 100644 --- a/23.merge-k-sorted-lists.js +++ b/problems/23.merge-k-sorted-lists.md @@ -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 * @@ -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; // 把小的添加到结果链表 @@ -83,3 +127,8 @@ var mergeKLists = function(lists) { return mergeTwoLists(mergeKLists(l1), mergeKLists(l2)); }; +``` + +## 相关题目 + +-[88.merge-sorted-array](./88.merge-sorted-array.md) diff --git a/thinkings/binary-tree-traversal.md b/thinkings/binary-tree-traversal.md index c58e0bf9d..75b0d28e7 100644 --- a/thinkings/binary-tree-traversal.md +++ b/thinkings/binary-tree-traversal.md @@ -40,8 +40,12 @@ BFS 的关键点在于如何记录每一层次是否遍历完成, 我们可以 其实从宏观上表现为:`自顶向下依次访问左侧链,然后自底向上依次访问右侧链`, 如果从这个角度出发去写的话,算法就不一样了。从上向下我们可以直接递归访问即可,从下向上我们只需要借助栈也可以轻易做到。 +整个过程大概是这样: + +![binary-tree-traversal-preorder](../assets/thinkings/binary-tree-traversal-preorder.png) + 这种思路解题有点像我总结过的一个解题思路`backtrack` - 回溯法。这种思路有一个好处就是 -可以`统一三种遍历的思路`. +可以`统一三种遍历的思路`. 这个很重要,如果不了解的朋友,希望能够记住这一点。 ## 中序遍历