提交 a86931fe 编写于 作者: L luzhipeng

feat: #121 #122 #198 #494 #309 #91

上级 edf7916a
......@@ -82,14 +82,17 @@ leetcode 题解,记录自己的 leetcode 解题之路。
#### 简单难度
- [0020.Valid Parentheses](./problems/20.validParentheses.md) 🖊
- [0020.Valid Parentheses](./problems/20.validParentheses.md)
- [0026.remove-duplicates-from-sorted-array](./problems/26.remove-duplicates-from-sorted-array.md)
- [0088.merge-sorted-array](./problems/88.merge-sorted-array.md)
- [0121.best-time-to-buy-and-sell-stock](./problems/121.best-time-to-buy-and-sell-stock.md) 🆕
- [0122.best-time-to-buy-and-sell-stock-ii](./problems/122.best-time-to-buy-and-sell-stock-ii.md) 🆕
- [0136.single-number](./problems/136.single-number.md)
- [0167.two-sum-ii-input-array-is-sorted](./problems/167.two-sum-ii-input-array-is-sorted.md)
- [0169.majority-element](./problems/169.majority-element.md)
- [0190.reverse-bits](./problems/190.reverse-bits.md)
- [0191.number-of-1-bits](./problems/191.number-of-1-bits.md)
- [0198.house-robber.md](./problems/198.house-robber.md) 🆕
- [0203.remove-linked-list-elements](./problems/203.remove-linked-list-elements.md)
- [0206.reverse-linked-list](./problems/206.reverse-linked-list.md)
- [0219.contains-duplicate-ii](./problems/219.contains-duplicate-ii.md)
......@@ -115,7 +118,8 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [0075.sort-colors](./problems/75.sort-colors.md)
- [0078.subsets](./problems/78.subsets.md) 🆕
- [0086.partition-list](./problems/86.partition-list.md)
- [0090.subsets-ii](./problems/90.subsets-ii.md) 🆕
- [0090.subsets-ii](./problems/90.subsets-ii.md)
- [0091.decode-ways](./problems/91.decode-ways.md) 🆕
- [0092.reverse-linked-list-ii](./problems/92.reverse-linked-list-ii.md)
- [0094.binary-tree-inorder-traversal](./problems/94.binary-tree-inorder-traversal.md)
- [0102.binary-tree-level-order-traversal](./problems/102.binary-tree-level-order-traversal.md)
......@@ -131,13 +135,15 @@ leetcode 题解,记录自己的 leetcode 解题之路。
- [0236.lowest-common-ancestor-of-a-binary-tree](./problems/236.lowest-common-ancestor-of-a-binary-tree.md)🆕
- [0238.product-of-array-except-self](./problems/238.product-of-array-except-self.md) 🆕
- [0240.search-a-2-d-matrix-ii](./problems/240.search-a-2-d-matrix-ii.md)
- [0279.perfect-squares](./problems/279.perfect-squares.md)🖊
- [0279.perfect-squares](./problems/279.perfect-squares.md)
- [0309.best-time-to-buy-and-sell-stock-with-cooldown](./problems/309.best-time-to-buy-and-sell-stock-with-cooldown.md) 🆕
- [0322.coin-change](./problems/322.coin-change.md)
- [0334.increasing-triplet-subsequence](./problems/334.increasing-triplet-subsequence.md)
- [0328.odd-even-linked-list](./problems/328.odd-even-linked-list.md)
- [0416.partition-equal-subset-sum](./problems/416.partition-equal-subset-sum.md)
- [0445.add-two-numbers-ii](./problems/445.add-two-numbers-ii.md)
- [0454.4-sum-ii](./problems/454.4-sum-ii.md) 🆕
- [0494.target-sum](./problems/494.target-sum.md) 🆕
- [0518.coin-change-2](./problems/518.coin-change-2.md)
- [0875.koko-eating-bananas](./problems/875.koko-eating-bananas.md)
- [0877.stone-game](./problems/877.stone-game.md)
......
<mxfile modified="2019-05-04T06:00:45.801Z" 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="8lZpRP_onmLUlqddJt9q" version="10.6.6" type="device"><diagram id="YQNoRghu4fKXr0qcQk76" name="第 1 页">7ZjbjtsgEIafxpcr2cZ2ksvETbattlXVrNRrZIiNgk2KyalPX1iDT7SNo60S7cq5iOAHBphvxhrbAXF+euRwl31hCFPHd9HJAR8c3595U/mvhHMlBJFXCSknqJJawpr8wlp0tbonCJediYIxKsiuKyasKHAiOhrknB270zaMdnfdwRRbwjqB1FZ/ECSySp36k0b/iEmamZ29aFaN5NBM1jcpM4jYsSWBpQNizpioWvkpxlT5zvilWrf6y2h9MI4LMWTB82b76bMbfv+JHt3ZE5w+oYevD9rKAdK9vrA+rDgbD+ACzZUjZa9ghRQXmcip7HmyWc3GyHJicyqvvquMEcxyLPhZTjk23gy1h7KWI43GMYWCHLrmoYaa1ubqHb4xIjf2XR1/XqTt6PDzDA1jomR7nmC9qu29nqH6QNoQiHqGBOQpFpYh2Whdu5Fe4FwByn8lqFJwtsUxo4y/zAarVeT6UT1igjt4A1AvshgKFXhdQ757W6jgnWffRf8OBjXtGZreFlQwZt9wFkOhBkHv2XzjR2r4zrPvon+Hggr7aRzcFlRkgZpYpAQ+iX/lnMa3IZT2JEhJWshuIqlhqS8OmAsiK8C5HsgJQmqbxTEjAq93MFF7HmW5KzXO9gXC6vSuMs8KoWtY3/RbWe/KXxzXoaM2wqdrg8csAF0oJgtbsRX8Ibb69U87jDrcroXk2aWkN1Lye5TA5N6Y7EIyHDH5s96j8u6Y7NIQjJhA722uxnY3THZhGI2YAhO9JpvAvTHZpV4wYgp79WHt/7thsgs9x4+oooLIQTZT8XLzSip3sKi1cOHJ24ZyibvApapdn0mOHfWxUEl7dW1YIPm/rg6yFizZGlPytB1rjdzZ9y0GzGQ5j5bufyo5J92ACTw7YOoC55URI7vNp9HqRaL5vgyWvwE=</diagram></mxfile>
\ No newline at end of file
<mxfile modified="2019-05-04T06:06:00.266Z" 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="emzrtnCmL0sRbl5TDGoR" version="10.6.6" type="device"><diagram id="SQUxga718U24Nse9CxR8" name="第 1 页">7ZhNj9sgEIZ/TY6VjLGd5BinSTeHSpVStVUvFTKzNlpsIkK++usLa7CNve1mtVWiXSUHB15ggHkGZ8IIz8vjJ0k2xWdBgY/CgB5H+OMoDKdoop9GONVClKBayCWjtdQR1uw3WDGw6o5R2HodlRBcsY0vZqKqIFOeRqQUB7/bveD+rBuSw0BYZ4QP1e+MqqJWJ+G41e+A5YWbGSXTuqUkrrPdybYgVBw6El6M8FwKoepSeZwDN75zfqnHLf/S2ixMQqXOGZCK5NdJTNEPsfqWrVLgh593H6yVPeE7u2G7WHVyHoCKzowjda0SlRbTQpVc15Au1r2BDpzYrgo1e9UxAqIEJU+6y6H1Zmw9VHQc6TQJnCi2980TCzVvzDUzfBFMTxwGNv5QYu3Y8EOOhjOxFTuZgR3V9V7PULMgawgnPUOKyBzUwJAudLbdSo9wXgAqfCWorZLiAeaCC/nYGy+XSRAmTYsL7ugNQH2WxblQMfINhcFloeJ3fvqe9e/ZoCY9Q5PLgopup+98FudCjaLeu/nCr9T4nZ++Z/17Lqi4f4yjy4JKBqDGA1IKjupfZ87iu2ec9yTCWV7paqapgdbTPUjFdAY4sw0lo9RMkx4KpmC9IZmZ86DTXa1JsasomNUHxryolM1hQ1fvnPpAf+bzJnTMRHB8afC4AdiH4k5hJ7aiJ2Krn/90w8jj9lJI4wEkdIMU9iDh8ZUpTQaU4hulcNp7UV6b0nRACd8o4d5fuYbatSi5X8UOpuSGKULYP0z42piGdxzRDVPcSw4b/18N01M3HAk3VCjb62KuHndeS9sNqRotTpHuHOshQQpbk7h+ZSWMzE2hkXZm26Si+rmuF7JWInvQ36uVs6eX7JlsZW/ytxg148UsWQT/Kekc+1EToWHUNDnOK8NGV9vL0fqvRHvDjBd/AA==</diagram></mxfile>
\ No newline at end of file
<mxfile modified="2019-05-04T07:56:58.484Z" 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="hGB--1jqNR12-NSJQ5r-" version="10.6.6" type="device"><diagram id="os5A9CisSlN9ZKPxQJiw" name="第 1 页">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</diagram></mxfile>
\ No newline at end of file
<mxfile modified="2019-05-04T08:50:46.975Z" 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="EDJk86jsYYBlklMIT5Au" version="10.6.6" type="device"><diagram id="4IO8ltCWfnja1ZXnyxj4" name="第 1 页">7Vxrb6M4FP01kbYjNQLbQPKxeXRfM6NI1Wh3Pq0IOAlawCw4Tbq/fu3wtt1NJg0xmelIneILGDjncLjX4A7gNNr/nLrJ5hPxcTgAhr8fwNkAgLE5Yv/zwEseQLaZB9Zp4OehRuAp+BcXQaOIbgMfZ60NKSEhDZJ20CNxjD3airlpSnbtzVYkbB81cddYCjx5bihH/wh8usmjI+DU8V9wsN6URzbtcb4mcsuNiyvJNq5Pdo0QnA/gNCWE5kvRfopDjl2JS77f4ytrqxNLcUxP2eH3TfDr53Qx/WrOfnuwPnoJflrcF708u+G2fcEZfSkhSMk29jHvxRjAyW4TUPyUuB5fu2Ocs9iGRiFrmWyx6A+nFO9fPVGzunwmG0wiTNMXtkm5Q8l9IRmraO5q/MvQpgF9GXMLxtdVxzUobKHA5RswAhJGQD9Gdr8wghJGUDtGoGc6QhJGSD9GPdORJWFkaccI9kxH9g14tuloBmnUQ9MWDUk7SOX59Mq2xdtNP0pykqTfuFHvUJLTJP3WbfUOJTlRGoCJhBPriRU4+DhGbpbkVc8q2HNcJysS06KKAhfLNa02iMiSQEQKEFFnIMqZ1H2HEK6CMJySkKSHjuFq5GHPY/GMpuRv3FizHFnIMroBHRi6QZdTs26VqwV2IR3WL3U52etS6pdHUL9unR9Bt6B3Hi0n4D0XrgihfuWOby9XgDbqlw6BXOJ8d7mCCLp25QK5YvoOPRfZds+0LpdgPfdcEUL9ylXVZ28pYruoxywhxRrLRa0SNbsz1OSCjLrpGlMWOzQNeViJXT9tQ9W+WWMSY+HOLkJuGKxj1vQYXpjFJxzNwHPDh2JFFPh++JrC2+x1QI8F2vTYsqRNoGAHdMaOXLnF2yi7EUZ4u2HgzvzBnl+qxm4nfIqxIce6Jk+9HNgXs+KxLOfrvo2V6zn9Y9aV3fYGJbn80j8aC0HfUJIrrIRkAQ2e8W264+PjbMxSqouw5bTJql7LHEnNOrNHKFdyb1P0FVIzONKdmkG5FHsjbB08VOBIsxFAuXLS/4pPfKjoR0lO82O8dt/tUmGXyNBtl6r3NXZICxQG/JPJEgj7ny3/CpHBAMeObzhOM2Sv898Tk1dzfBiHV3PFEjuIcc9+QPEbNSu+/Gjs7PMDlh1d0rM7JBQ5gkkB+fZTFgjdeblcIJxCqXH41ww14C+DvIP77IDsA2fPTvYKERz2OInVH+7+RyYYCoI5cTywOwtQvfo6TS+eJ7P/9OXTT4s7fqPzpc931a1ejvXkXS/TWhTX0kqIV/RmlCK+IkWKJNFC1xx5QHKSWJGd+3zNuGIc/ybu9Zk1H83QhYb4jhMIrjrEh+T8teZNQaPtRhzAeJklN2velyVUNO8ecHpeAveae/OuPrQU0fLuhkD44PDdu5ufO8vAUlRp13Xz89PE/33snyEYwWaMc0PvWjxLizbUnlmoUlCBJBz7D3ymXg3+6QUfF+10WvFaTtGDEtPNbfE+oH9ydobmqGh+5YcbmkVrti+4OzReGo0FTgOGDH+0zeq3UNiXJhEKlLELJtvUw0dvW5nbE0d7UhzmIzHNg6r4LI6wIMHBC8qxeWckPAFtNC4jZTf5NRR71sqQOrMM+1hXuY1IXR1EVl38G3R3yvyPm0hzKtVewB+gA9u82LI/XLVCRapP3ASWEq4RnM6f2UVmJU/lXFoOoO9mmwrNY2SG7hKHi8NLHqJk8KOwwZJQSiIFxZQkKiWwU0v4mUf7NZ8QPYwyz8VDHycp9lyK/WFCMrblX25ueeKnS4YxmT6Ca8tCnOCmGOlSfYVjdSSL0tPeZdErWTidyYI164nw+TOg/msCcP4f</diagram></mxfile>
\ No newline at end of file
/*
* @lc app=leetcode id=108 lang=javascript
*
* [108] Convert Sorted Array to Binary Search Tree
*
* https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/
*
* algorithms
* Easy (49.37%)
* Total Accepted: 255.2K
* Total Submissions: 507.2K
* Testcase Example: '[-10,-3,0,5,9]'
*
* Given an array where elements are sorted in ascending order, convert it to a
* height balanced BST.
*
* For this problem, a height-balanced binary tree is defined as a binary tree
* in which the depth of the two subtrees of every node never differ by more
* than 1.
*
* Example:
*
*
* Given the sorted array: [-10,-3,0,5,9],
*
* One possible answer is: [0,-3,9,-10,null,5], which represents the following
* height balanced BST:
*
* ⁠ 0
* ⁠ / \
* ⁠ -3 9
* ⁠ / /
* ⁠-10 5
*
*
*/
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number[]} nums
* @return {TreeNode}
*/
var sortedArrayToBST = function(nums) {
// 由于数组是排序好的,因此一个思路就是将数组分成两半,一半是左子树,另一半是右子树
// 然后运用“树的递归性质”递归完成操作即可。
if(nums.length === 0) return null;
const mid = nums.length >> 1;
const root = new TreeNode(nums[mid]);
root.left = sortedArrayToBST(nums.slice(0, mid));
root.right = sortedArrayToBST(nums.slice(mid + 1))
return root;
// 扩展: 这道题启示我们如果是一个非排序的数组,我们可以先进行排序然后再按上述思路进行。
};
/*
* @lc app=leetcode id=202 lang=javascript
*
* [202] Happy Number
*
* https://leetcode.com/problems/happy-number/description/
*
* algorithms
* Easy (44.36%)
* Total Accepted: 227.2K
* Total Submissions: 505.7K
* Testcase Example: '19'
*
* Write an algorithm to determine if a number is "happy".
*
* A happy number is a number defined by the following process: Starting with
* any positive integer, replace the number by the sum of the squares of its
* digits, and repeat the process until the number equals 1 (where it will
* stay), or it loops endlessly in a cycle which does not include 1. Those
* numbers for which this process ends in 1 are happy numbers.
*
* Example: 
*
*
* Input: 19
* Output: true
* Explanation:
* 1^2 + 9^2 = 82
* 8^2 + 2^2 = 68
* 6^2 + 8^2 = 100
* 1^2 + 0^2 + 0^2 = 1
*
*/
function squareSum(n) {
let sum = 0, tmp;
while (n) {
tmp = n % 10;
sum += tmp * tmp;
n = Math.floor(n / 10);
}
return sum;
}
function isHappyWithMapper(n, visited) {
if (n === 1) return true;
if (visited[n]) return false;
visited[n] = true;
return isHappyWithMapper(squareSum(n), visited);
}
/**
* @param {number} n
* @return {boolean}
*/
var isHappy = function(n) {
const visited = {};
return isHappyWithMapper(n, visited);
};
/*
* @lc app=leetcode id=204 lang=javascript
*
* [204] Count Primes
*
* https://leetcode.com/problems/count-primes/description/
*
* algorithms
* Easy (28.33%)
* Total Accepted: 229.8K
* Total Submissions: 798.7K
* Testcase Example: '10'
*
* Count the number of prime numbers less than a non-negative number, n.
*
* Example:
*
*
* Input: 10
* Output: 4
* Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.
*
*
*/
/**
* @param {number} n
* @return {number}
*/
var countPrimes = function(n) {
// tag: 数论
// if (n <= 2) return 0;
// let compositionCount = 0;
// for(let i = 3; i < n; i++) {
// for(let j = i - 1; j > 1 ; j--) {
// if (i % j === 0) {
// compositionCount++;
// break; // 找到一个就可以证明它不是质数了
// }
// }
// }
// return n - compositionCount - 2; // 需要减去1和n这两个数字
// 上面的方法会超时,因此我们需要进行优化
// 数学角度来看,如果一个数字可以分解为两个数字相乘(这两个数字不包括0和它本身),那么它就是合数
const compositions = []; // compositions[i] 表示i是否是合数
let count = 0;
for(let i = 2; i < n; i++) {
if (!compositions[i]) count++;
for(let j = 2; i * j < n; j++) {
compositions[i * j] = true;
}
}
return count;
};
/*
* @lc app=leetcode id=21 lang=javascript
*
* [21] Merge Two Sorted Lists
*
* https://leetcode.com/problems/merge-two-sorted-lists/description/
*
* algorithms
* Easy (46.02%)
* Total Accepted: 562.7K
* Total Submissions: 1.2M
* Testcase Example: '[1,2,4]\n[1,3,4]'
*
* Merge two sorted linked lists and return it as a new list. The new list
* should be made by splicing together the nodes of the first two lists.
*
* Example:
*
* Input: 1->2->4, 1->3->4
* Output: 1->1->2->3->4->4
*
*
*/
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var mergeTwoLists = function(l1, l2) {
let current = new ListNode();
const dummy = current;
while (l1 || l2) {
if (!l1) {
current.next = l2;
return dummy.next;
} else if (!l2) {
current.next = l1;
return dummy.next;
}
if (l1.val <= l2.val) {
current.next = l1;
l1 = l1.next;
} else {
current.next = l2;
l2 = l2.next;
}
current = current.next;
}
return dummy.next;
// if (l1 === null) return l2;
// if (l2 === null) return l1;
// if (l1.val < l2.val) {
// l1.next = mergeTwoLists(l1.next, l2);
// return l1;
// } else {
// l2.next = mergeTwoLists(l1, l2.next);
// return l2;
// }
};
/*
* @lc app=leetcode id=268 lang=javascript
*
* [268] Missing Number
*
* https://leetcode.com/problems/missing-number/description/
*
* algorithms
* Easy (47.60%)
* Total Accepted: 267.7K
* Total Submissions: 556.2K
* Testcase Example: '[3,0,1]'
*
* Given an array containing n distinct numbers taken from 0, 1, 2, ..., n,
* find the one that is missing from the array.
*
* Example 1:
*
*
* Input: [3,0,1]
* Output: 2
*
*
* Example 2:
*
*
* Input: [9,6,4,2,3,5,7,0,1]
* Output: 8
*
*
* Note:
* Your algorithm should run in linear runtime complexity. Could you implement
* it using only constant extra space complexity?
*/
/**
* @param {number[]} nums
* @return {number}
*/
var missingNumber = function(nums) {
// 缺失的数字一定是 0 到 n 之间的一个数字
// 这是一道数论的题目
// 这里用到了一条性质: sum([1,n]) = n * (n+1) / 2
let sum = 0;
for(let num of nums)
sum += num;
return (nums.length * (nums.length + 1) )/ 2 - sum;
};
/*
* @lc app=leetcode id=338 lang=javascript
*
* [338] Counting Bits
*
* https://leetcode.com/problems/counting-bits/description/
*
* algorithms
* Medium (64.04%)
* Total Accepted: 163.1K
* Total Submissions: 253K
* Testcase Example: '2'
*
* Given a non negative integer number num. For every numbers i in the range 0
* ≤ i ≤ num calculate the number of 1's in their binary representation and
* return them as an array.
*
* Example 1:
*
*
* Input: 2
* Output: [0,1,1]
*
* Example 2:
*
*
* Input: 5
* Output: [0,1,1,2,1,2]
*
*
* Follow up:
*
*
* It is very easy to come up with a solution with run time
* O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a
* single pass?
* Space complexity should be O(n).
* Can you do it like a boss? Do it without using any builtin function like
* __builtin_popcount in c++ or in any other language.
*
*/
/**
* @param {number} num
* @return {number[]}
*/
var countBits = function(num) {
// 这是一道位运算的题目
const res = [];
res[0] = 0;
for (let i = 1; i <= num; i++) {
if ((i & 1) === 0) { // 偶数
res[i] = res[i >> 1]; // 偶数不影响结果
} else { // 奇数
res[i] = res[i - 1] + 1; // 如果是奇数,那就是前面的数字 + 1
}
}
return res;
};
## 题目地址
https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/
## 题目描述
```
Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.
Note that you cannot sell a stock before you buy one.
Example 1:
Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Not 7-1 = 6, as selling price needs to be larger than buying price.
Example 2:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
```
## 思路
由于我们是想获取到最大的利润,我们的策略应该是低点买入,高点卖出。
由于题目对于交易次数有限制,只能交易一次,因此问题的本质其实就是求相邻波峰浪谷的差值的最大值。
用图表示的话就是这样:
> 如下图,我们只需要求出加粗部分的最大值即可
![121.best-time-to-buy-and-sell-stock](../assets/problems/121.best-time-to-buy-and-sell-stock.png)
## 关键点解析
- 这类题只要你在心中(或者别的地方)画出上面这种图就很容易解决
## 代码
```js
/*
* @lc app=leetcode id=121 lang=javascript
*
* [121] Best Time to Buy and Sell Stock
*
* https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/
*
* algorithms
* Easy (46.34%)
* Total Accepted: 480.5K
* Total Submissions: 1M
* Testcase Example: '[7,1,5,3,6,4]'
*
* Say you have an array for which the i^th element is the price of a given
* stock on day i.
*
* If you were only permitted to complete at most one transaction (i.e., buy
* one and sell one share of the stock), design an algorithm to find the
* maximum profit.
*
* Note that you cannot sell a stock before you buy one.
*
* Example 1:
*
*
* Input: [7,1,5,3,6,4]
* Output: 5
* Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit
* = 6-1 = 5.
* Not 7-1 = 6, as selling price needs to be larger than buying price.
*
*
* Example 2:
*
*
* Input: [7,6,4,3,1]
* Output: 0
* Explanation: In this case, no transaction is done, i.e. max profit = 0.
*
*
*/
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
let min = prices[0];
let profit = 0;
// 7 1 5 3 6 4
for(let i = 1; i < prices.length; i++) {
if (prices[i] > prices[i -1]) {
profit = Math.max(profit, prices[i] - min);
} else {
min = Math.min(min, prices[i]);;
}
}
return profit;
};
```
## 相关题目
- [122.best-time-to-buy-and-sell-stock-ii](./122.best-time-to-buy-and-sell-stock-ii.md)
- [309.best-time-to-buy-and-sell-stock-with-cooldown](./309.best-time-to-buy-and-sell-stock-with-cooldown.md)
## 题目地址
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/
## 题目描述
```
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).
Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
Example 1:
Input: [7,1,5,3,6,4]
Output: 7
Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
Example 2:
Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
engaging multiple transactions at the same time. You must sell before buying again.
Example 3:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
```
## 思路
由于我们是想获取到最大的利润,我们的策略应该是低点买入,高点卖出。
由于题目对于交易次数没有限制,因此只要能够赚钱的机会我们都不应该放过。
> 如下图,我们只需要求出加粗部分的总和即可
用图表示的话就是这样:
![122.best-time-to-buy-and-sell-stock-ii](../assets/problems/122.best-time-to-buy-and-sell-stock-ii.png)
## 关键点解析
- 这类题只要你在心中(或者别的地方)画出上面这种图就很容易解决
## 代码
```js
/*
* @lc app=leetcode id=122 lang=javascript
*
* [122] Best Time to Buy and Sell Stock II
*
* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/
*
* algorithms
* Easy (50.99%)
* Total Accepted: 315.5K
* Total Submissions: 610.9K
* Testcase Example: '[7,1,5,3,6,4]'
*
* Say you have an array for which the i^th element is the price of a given
* stock on day i.
*
* Design an algorithm to find the maximum profit. You may complete as many
* transactions as you like (i.e., buy one and sell one share of the stock
* multiple times).
*
* Note: You may not engage in multiple transactions at the same time (i.e.,
* you must sell the stock before you buy again).
*
* Example 1:
*
*
* Input: [7,1,5,3,6,4]
* Output: 7
* Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit
* = 5-1 = 4.
* Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 =
* 3.
*
*
* Example 2:
*
*
* Input: [1,2,3,4,5]
* Output: 4
* Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit
* = 5-1 = 4.
* Note that you cannot buy on day 1, buy on day 2 and sell them later, as you
* are
* engaging multiple transactions at the same time. You must sell before buying
* again.
*
*
* Example 3:
*
*
* Input: [7,6,4,3,1]
* Output: 0
* Explanation: In this case, no transaction is done, i.e. max profit = 0.
*
*/
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
let profit = 0;
for(let i = 1; i < prices.length; i++) {
if (prices[i] > prices[i -1]) {
profit = profit + prices[i] - prices[i - 1];
}
}
return profit;
};
```
## 相关题目
- [121.best-time-to-buy-and-sell-stock](./121.best-time-to-buy-and-sell-stock.md)
- [309.best-time-to-buy-and-sell-stock-with-cooldown](./309.best-time-to-buy-and-sell-stock-with-cooldown.md)
## 题目地址
https://leetcode.com/problems/house-robber/description/
## 题目描述
```
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
Example 1:
Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
Example 2:
Input: [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
Total amount you can rob = 2 + 9 + 1 = 12.
```
## 思路
这是一道非常典型且简单的动态规划问题,但是在这里我希望通过这个例子,
让大家对动态规划问题有一点认识。
为什么别人的动态规划可以那么写,为什么没有用 dp 数组就搞定了。
比如别人的爬楼梯问题怎么就用 fibnacci 搞定了?为什么?在这里我们就来看下。
思路还是和其他简单的动态规划问题一样,我们本质上在解决`对于第[i] 个房子,我们抢还是不抢。`的问题。
判断的标准就是总价值哪个更大, 那么对于抢的话`就是当前的房子可以抢的价值 + dp[i - 2]`
> i - 1 不能抢,否则会触发警铃
如果不抢的话,就是`dp[i - 1]`.
> 这里的 dp 其实就是`子问题`.
状态转移方程也不难写`dp[i] = Math.max(dp[i - 2] + nums[i - 2], dp[i - 1]);`.
上述过程用图来表示的话,是这样的:
![198.house-robber](../assets/problems/198.house-robber.png)
我们仔细观察的话,其实我们只需要保证前一个 dp[i - 1] 和 dp[i - 2] 两个变量就好了,
比如我们计算到 i = 6 的时候,即需要计算 dp[6]的时候, 我们需要 dp[5], dp[4],但是我们
不需要 dp[3], dp[2] ...
因此代码可以简化为:
```js
let a = 0;
let b = 0;
for (let i = 0; i < nums.length; i++) {
const temp = b;
b = Math.max(a + nums[i], b);
a = temp;
}
return b;
```
如上的代码,我们可以将复杂度进行优化,从 O(n)降低到 O(1),
类似的优化在 DP 问题中不在少数。
> 动态规划问题是递归问题查表,避免重复计算,从而节省时间。
> 如果我们对问题加以分析和抽象,有可能对空间上进一步优化
## 关键点解析
## 代码
```js
/*
* @lc app=leetcode id=198 lang=javascript
*
* [198] House Robber
*
* https://leetcode.com/problems/house-robber/description/
*
* algorithms
* Easy (40.80%)
* Total Accepted: 312.1K
* Total Submissions: 762.4K
* Testcase Example: '[1,2,3,1]'
*
* You are a professional robber planning to rob houses along a street. Each
* house has a certain amount of money stashed, the only constraint stopping
* you from robbing each of them is that adjacent houses have security system
* connected and it will automatically contact the police if two adjacent
* houses were broken into on the same night.
*
* Given a list of non-negative integers representing the amount of money of
* each house, determine the maximum amount of money you can rob tonight
* without alerting the police.
*
* Example 1:
*
*
* Input: [1,2,3,1]
* Output: 4
* Explanation: Rob house 1 (money = 1) and then rob house 3 (money =
* 3).
* Total amount you can rob = 1 + 3 = 4.
*
* Example 2:
*
*
* Input: [2,7,9,3,1]
* Output: 12
* Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house
* 5 (money = 1).
* Total amount you can rob = 2 + 9 + 1 = 12.
*
*
*/
/**
* @param {number[]} nums
* @return {number}
*/
var rob = function(nums) {
// Tag: DP
const dp = [];
dp[0] = 0;
dp[1] = 0;
for (let i = 2; i < nums.length + 2; i++) {
dp[i] = Math.max(dp[i - 2] + nums[i - 2], dp[i - 1]);
}
return dp[nums.length + 1];
};
```
## 题目地址
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/
## 题目描述
```
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)
Example:
Input: [1,2,3,0,2]
Output: 3
Explanation: transactions = [buy, sell, cooldown, buy, sell]
```
## 思路
这是一道典型的DP问题, DP 问题的核心是找到状态和状态转移方程。
这道题目的状态似乎比我们常见的那种DP问题要多,这里的状态有buy sell cooldown三种,
我们可以用三个数组来表示这这三个状态,buy,sell, cooldown.
- buy[i]表示第i天,且以buy结尾的最大利润
- sell[i]表示第i天,且以sell结尾的最大利润
- cooldown[i]表示第i天,且以sell结尾的最大利润
我们思考一下,其实cooldown这个状态数组似乎没有什么用,因此cooldown不会对`profit`产生
任何影响。 我们可以进一步缩小为两种状态。
- buy[i] 表示第i天,且以buy或者coolwown结尾的最大利润
- sell[i] 表示第i天,且以sell或者cooldown结尾的最大利润
对应的状态转移方程如下:
> 这个需要花点时间来理解
```
buy[i] = Math.max(buy[i - 1], sell[i - 2] - prices[i]);
sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);
```
我们来分析一下,buy[i]对应第i的action只能是buy或者cooldown。
- 如果是cooldown,那么profit就是 buy[i - 1]
- 如果是buy,那么就是`前一个卖的profit减去今天买股票花的钱`,即 sell[i -2] - prices[i]
> 注意这里是i - 2,不是 i-1 ,因为有cooldown的限制
sell[i]对应第i的action只能是sell或者cooldown。
- 如果是cooldown,那么profit就是 sell[i - 1]
- 如果是sell,那么就是`前一次买的时候获取的利润加上这次卖的钱`,即 buy[i - 1] + prices[i]
## 关键点解析
- 多状态动态规划
## 代码
```js
/*
* @lc app=leetcode id=309 lang=javascript
*
* [309] Best Time to Buy and Sell Stock with Cooldown
*
* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/
*
* algorithms
* Medium (43.52%)
* Total Accepted: 88.3K
* Total Submissions: 201.4K
* Testcase Example: '[1,2,3,0,2]'
*
* Say you have an array for which the i^th element is the price of a given
* stock on day i.
*
* Design an algorithm to find the maximum profit. You may complete as many
* transactions as you like (ie, buy one and sell one share of the stock
* multiple times) with the following restrictions:
*
*
* You may not engage in multiple transactions at the same time (ie, you must
* sell the stock before you buy again).
* After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1
* day)
*
*
* Example:
*
*
* Input: [1,2,3,0,2]
* Output: 3
* Explanation: transactions = [buy, sell, cooldown, buy, sell]
*
*/
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
if (prices == null || prices.length <= 1) return 0;
// 定义状态变量
const buy = [];
const sell = [];
// 寻常
buy[0] = -prices[0];
buy[1] = Math.max(-prices[0], -prices[1]);
sell[0] = 0;
sell[1] = Math.max(0, prices[1] - prices[0]);
for (let i = 2; i < prices.length; i++) {
// 状态转移方程
// 第i天只能是买或者cooldown
// 如果买利润就是sell[i - 2] - prices[i], 注意这里是i - 2,不是 i-1 ,因为有cooldown的限制
// cooldown就是buy[i -1]
buy[i] = Math.max(buy[i - 1], sell[i - 2] - prices[i]);
// 第i天只能是卖或者cooldown
// 如果卖利润就是buy[i -1] + prices[i]
// cooldown就是sell[i -1]
sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);
}
return Math.max(buy[prices.length - 1], sell[prices.length - 1], 0);
};
```
## 相关题目
- [121.best-time-to-buy-and-sell-stock](./121.best-time-to-buy-and-sell-stock.md)
- [122.best-time-to-buy-and-sell-stock-ii](./122.best-time-to-buy-and-sell-stock-ii.md)
......@@ -43,7 +43,8 @@ The two tuples are:
## 关键点解析
- 空间换时间
- 两两分组,求出两两结合能够得出的可能数,然后合并即可。
## 代码
```js
......
## 题目地址
https://leetcode.com/problems/target-sum/description/
## 题目描述
```
You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols + and -. For each integer, you should choose one from + and - as its new symbol.
Find out how many ways to assign symbols to make sum of integers equal to target S.
Example 1:
Input: nums is [1, 1, 1, 1, 1], S is 3.
Output: 5
Explanation:
-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3
There are 5 ways to assign symbols to make the sum of nums be target 3.
Note:
The length of the given array is positive and will not exceed 20.
The sum of elements in the given array will not exceed 1000.
Your output answer is guaranteed to be fitted in a 32-bit integer.
```
## 思路
题目是给定一个数组,让你在数字前面添加 `+`或者`-`,使其和等于target.
![494.target-sum](../assets/problems/494.target-sum.png)
暴力法的时间复杂度是指数级别的,因此我们不予考虑。我们需要换种思路.
我们将最终的结果分成两组,一组是我们添加了`+`的,一组是我们添加了`-`的。
![494.target-sum-2](../assets/problems/494.target-sum-2.png)
如上图,问题转化为如何求其中一组,我们不妨求前面标`+`的一组
> 如果求出一组,另一组实际就已知了,即总集和这一组的差集。
通过进一步分析,我们得到了这样的关系:
![494.target-sum-3](../assets/problems/494.target-sum-3.png)
因此问题转化为,求解`sumCount(nums, target)`,即nums数组中能够组成
target的总数一共有多少种,这是一道我们之前做过的题目,使用动态规划可以解决。
## 关键点解析
- 对元素进行分组,分组的依据是符号, 是`+` 或者 `-`
- 通过数学公式推导可以简化我们的求解过程,这需要一点`数学知识和数学意志`
## 代码
```js
/*
* @lc app=leetcode id=494 lang=javascript
*
* [494] Target Sum
*
* https://leetcode.com/problems/target-sum/description/
*
* algorithms
* Medium (44.86%)
* Total Accepted: 89.3K
* Total Submissions: 198.5K
* Testcase Example: '[1,1,1,1,1]\n3'
*
*
* You are given a list of non-negative integers, a1, a2, ..., an, and a
* target, S. Now you have 2 symbols + and -. For each integer, you should
* choose one from + and - as its new symbol.
* ⁠
*
* Find out how many ways to assign symbols to make sum of integers equal to
* target S.
*
*
* Example 1:
*
* Input: nums is [1, 1, 1, 1, 1], S is 3.
* Output: 5
* Explanation:
*
* -1+1+1+1+1 = 3
* +1-1+1+1+1 = 3
* +1+1-1+1+1 = 3
* +1+1+1-1+1 = 3
* +1+1+1+1-1 = 3
*
* There are 5 ways to assign symbols to make the sum of nums be target 3.
*
*
*
* Note:
*
* The length of the given array is positive and will not exceed 20.
* The sum of elements in the given array will not exceed 1000.
* Your output answer is guaranteed to be fitted in a 32-bit integer.
*
*
*/
// 这个是我们熟悉的问题了
// 我们这里需要求解的是nums里面有多少种可以组成target的方式
var sumCount = function(nums, target) {
// 这里通过观察,我们没必要使用二维数组去存储这些计算结果
// 使用一维数组可以有效节省空间
const dp = Array(target + 1).fill(0);
dp[0] = 1;
for (let i = 0; i < nums.length; i++) {
for (let j = target; j >= nums[i]; j--) {
dp[j] += dp[j - nums[i]];
}
}
return dp[target];
};
const add = nums => nums.reduce((a, b) => (a += b), 0);
/**
* @param {number[]} nums
* @param {number} S
* @return {number}
*/
var findTargetSumWays = function(nums, S) {
const sum = add(nums);
if (sum < S) return 0;
if ((S + sum) % 2 === 1) return 0;
return sumCount(nums, (S + sum) >> 1);
};
```
## 题目地址
https://leetcode.com/problems/decode-ways/description/
## 题目描述
```
A message containing letters from A-Z is being encoded to numbers using the following mapping:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Given a non-empty string containing only digits, determine the total number of ways to decode it.
Example 1:
Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).
Example 2:
Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
```
## 思路
这道题目和爬楼梯问题有异曲同工之妙。
这也是一道典型的动态规划题目。我们来思考:
- 对于一个数字来说[1,9]这九个数字能够被识别为一种编码方式
- 对于两个数字来说[10, 26]这几个数字能被识别为一种编码方式
我们考虑用dp[i]来切分子问题, 那么dp[i]表示的意思是当前字符串的以索引i结尾的子问题。
这样的话,我们最后只需要取dp[s.length] 就可以解决问题了。
关于递归公式,让我们`先局部后整体`。对于局部,我们遍历到一个元素的时候,
我们有两种方式来组成编码方式,第一种是这个元素本身(需要自身是[1,9]),
第二种是它和前一个元素组成[10, 26]。 用伪代码来表示的话就是:
`dp[i] = 以自身去编码(一位) + 以前面的元素和自身去编码(两位)` .这显然是完备的,
这样我们通过层层推导就可以得到结果。
## 关键点解析
- 爬楼梯问题(我把这种题目统称为爬楼梯问题)
## 代码
```js
/*
* @lc app=leetcode id=91 lang=javascript
*
* [91] Decode Ways
*
* https://leetcode.com/problems/decode-ways/description/
*
* algorithms
* Medium (21.93%)
* Total Accepted: 254.4K
* Total Submissions: 1.1M
* Testcase Example: '"12"'
*
* A message containing letters from A-Z is being encoded to numbers using the
* following mapping:
*
*
* 'A' -> 1
* 'B' -> 2
* ...
* 'Z' -> 26
*
*
* Given a non-empty string containing only digits, determine the total number
* of ways to decode it.
*
* Example 1:
*
*
* Input: "12"
* Output: 2
* Explanation: It could be decoded as "AB" (1 2) or "L" (12).
*
*
* Example 2:
*
*
* Input: "226"
* Output: 3
* Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2
* 6).
*
*/
/**
* @param {string} s
* @return {number}
*/
var numDecodings = function(s) {
if (s == null || s.length == 0) {
return 0;
}
const dp = Array(s.length + 1).fill(0);
dp[0] = 1;
dp[1] = s[0] !== "0" ? 1 : 0;
for (let i = 2; i < s.length + 1; i++) {
const one = +s.slice(i - 1, i);
const two = +s.slice(i - 2, i);
if (two >= 10 && two <= 26) {
dp[i] = dp[i - 2];
}
if (one >= 1 && one <= 9) {
dp[i] += dp[i - 1];
}
}
return dp[dp.length - 1];
};
```
## 扩展
如果编码的范围不再是1-26,而是三位的话怎么办?
......@@ -155,10 +155,15 @@ f(n) = f(n-1) + f(n-2) 就是【状态转移公式】
### 相关问题
- [硬币找零问题](../problems/322.coin-change.md)
- [硬币找零问题2](../problems/518.coin-change-2.md)
- [分词问题](../problems/139.word-break.md)
- [416.partition-equal-subset-sum](../problems/416.partition-equal-subset-sum.md)
- [0091.decode-ways](../problems/91.decode-ways.md)
- [0139.word-break](../problems/139.word-break.md)
- [0198.house-robber](../problems/0198.house-robber.md)
- [0309.best-time-to-buy-and-sell-stock-with-cooldown](../problems/309.best-time-to-buy-and-sell-stock-with-cooldown.md)
- [0322.coin-change](../problems/322.coin-change.md)
- [0416.partition-equal-subset-sum](../problems/416.partition-equal-subset-sum.md)
- [0518.coin-change-2](../problems/518.coin-change-2.md)
> 太多了,没有逐一列举
## 总结
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册