Skip to content

Commit 1b5dc5f

Browse files
author
luzhipeng
committedApr 28, 2019
feat: 部分文件增加内容
1 parent 8bdef01 commit 1b5dc5f

18 files changed

+829
-12
lines changed
 

Diff for: ‎152.maximum-product-subarray.js

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* @lc app=leetcode id=152 lang=javascript
3+
*
4+
* [152] Maximum Product Subarray
5+
*
6+
* https://leetcode.com/problems/maximum-product-subarray/description/
7+
*
8+
* algorithms
9+
* Medium (28.61%)
10+
* Total Accepted: 202.8K
11+
* Total Submissions: 700K
12+
* Testcase Example: '[2,3,-2,4]'
13+
*
14+
* Given an integer array nums, find the contiguous subarray within an array
15+
* (containing at least one number) which has the largest product.
16+
*
17+
* Example 1:
18+
*
19+
*
20+
* Input: [2,3,-2,4]
21+
* Output: 6
22+
* Explanation: [2,3] has the largest product 6.
23+
*
24+
*
25+
* Example 2:
26+
*
27+
*
28+
* Input: [-2,0,-1]
29+
* Output: 0
30+
* Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
31+
*
32+
*/
33+
/**
34+
* @param {number[]} nums
35+
* @return {number}
36+
*/
37+
var maxProduct = function(nums) {
38+
// let max = nums[0];
39+
// let temp = null;
40+
// for(let i = 0; i < nums.length; i++) {
41+
// temp = nums[i];
42+
// max = Math.max(temp, max);
43+
// for(let j = i + 1; j < nums.length; j++) {
44+
// temp *= nums[j];
45+
// max = Math.max(temp, max);
46+
// }
47+
// }
48+
49+
// return max;
50+
let max = nums[0];
51+
let min = nums[0];
52+
let res = nums[0];
53+
54+
for (let i = 1; i < nums.length; i++) {
55+
let tmp = min;
56+
min = Math.min(nums[i], Math.min(max * nums[i], min * nums[i])); // 取最小
57+
max = Math.max(nums[i], Math.max(max * nums[i], tmp * nums[i])); /// 取最大
58+
res = Math.max(res, max);
59+
}
60+
return res;
61+
};

Diff for: ‎189.rotate-array.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* @lc app=leetcode id=189 lang=javascript
3+
*
4+
* [189] Rotate Array
5+
*
6+
* https://leetcode.com/problems/rotate-array/description/
7+
*
8+
* algorithms
9+
* Easy (29.07%)
10+
* Total Accepted: 287.3K
11+
* Total Submissions: 966.9K
12+
* Testcase Example: '[1,2,3,4,5,6,7]\n3'
13+
*
14+
* Given an array, rotate the array to the right by k steps, where k is
15+
* non-negative.
16+
*
17+
* Example 1:
18+
*
19+
*
20+
* Input: [1,2,3,4,5,6,7] and k = 3
21+
* Output: [5,6,7,1,2,3,4]
22+
* Explanation:
23+
* rotate 1 steps to the right: [7,1,2,3,4,5,6]
24+
* rotate 2 steps to the right: [6,7,1,2,3,4,5]
25+
* rotate 3 steps to the right: [5,6,7,1,2,3,4]
26+
*
27+
*
28+
* Example 2:
29+
*
30+
*
31+
* Input: [-1,-100,3,99] and k = 2
32+
* Output: [3,99,-1,-100]
33+
* Explanation:
34+
* rotate 1 steps to the right: [99,-1,-100,3]
35+
* rotate 2 steps to the right: [3,99,-1,-100]
36+
*
37+
*
38+
* Note:
39+
*
40+
*
41+
* Try to come up as many solutions as you can, there are at least 3 different
42+
* ways to solve this problem.
43+
* Could you do it in-place with O(1) extra space?
44+
*
45+
*/
46+
/**
47+
* @param {number[]} nums
48+
* @param {number} k
49+
* @return {void} Do not return anything, modify nums in-place instead.
50+
*/
51+
var rotate = function(nums, k) {
52+
// 就像扩容一样操作
53+
k = k % nums.length;
54+
const n = nums.length;
55+
56+
for (let i = nums.length - 1; i >= 0; i--) {
57+
nums[i + k] = nums[i];
58+
}
59+
60+
for (let i = 0; i < k; i++) {
61+
nums[i] = nums[n + i];
62+
}
63+
nums.length = n;
64+
};

Diff for: ‎217.contains-duplicate.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* @lc app=leetcode id=217 lang=javascript
3+
*
4+
* [217] Contains Duplicate
5+
*
6+
* https://leetcode.com/problems/contains-duplicate/description/
7+
*
8+
* algorithms
9+
* Easy (50.92%)
10+
* Total Accepted: 324K
11+
* Total Submissions: 628.5K
12+
* Testcase Example: '[1,2,3,1]'
13+
*
14+
* Given an array of integers, find if the array contains any duplicates.
15+
*
16+
* Your function should return true if any value appears at least twice in the
17+
* array, and it should return false if every element is distinct.
18+
*
19+
* Example 1:
20+
*
21+
*
22+
* Input: [1,2,3,1]
23+
* Output: true
24+
*
25+
* Example 2:
26+
*
27+
*
28+
* Input: [1,2,3,4]
29+
* Output: false
30+
*
31+
* Example 3:
32+
*
33+
*
34+
* Input: [1,1,1,3,3,4,3,2,4,2]
35+
* Output: true
36+
*
37+
*/
38+
/**
39+
* @param {number[]} nums
40+
* @return {boolean}
41+
*/
42+
var containsDuplicate = function(nums) {
43+
// 1. 暴力两层循环两两比较, 时间复杂度O(n^2) 空间复杂度O(1)
44+
45+
// 2. 先排序,之后比较前后元素是否一致即可,一层循环即可,如果排序使用的比较排序的话时间复杂度O(nlogn) 空间复杂度O(1)
46+
47+
// 3. 用hashmap ,时间复杂度O(n) 空间复杂度O(n)
48+
const visited = {};
49+
for(let i = 0; i < nums.length; i++) {
50+
if (visited[nums[i]]) return true;
51+
visited[nums[i]] = true;
52+
}
53+
return false;
54+
};
55+

Diff for: ‎23.merge-k-sorted-lists.js

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* @lc app=leetcode id=23 lang=javascript
3+
*
4+
* [23] Merge k Sorted Lists
5+
*
6+
* https://leetcode.com/problems/merge-k-sorted-lists/description/
7+
*
8+
* algorithms
9+
* Hard (33.14%)
10+
* Total Accepted: 373.7K
11+
* Total Submissions: 1.1M
12+
* Testcase Example: '[[1,4,5],[1,3,4],[2,6]]'
13+
*
14+
* Merge k sorted linked lists and return it as one sorted list. Analyze and
15+
* describe its complexity.
16+
*
17+
* Example:
18+
*
19+
*
20+
* Input:
21+
* [
22+
* 1->4->5,
23+
* 1->3->4,
24+
* 2->6
25+
* ]
26+
* Output: 1->1->2->3->4->4->5->6
27+
*
28+
*
29+
*/
30+
function mergeTwoLists(l1, l2) {
31+
const dummyHead = {};
32+
let current = dummyHead;
33+
// 1 -> 3 -> 5
34+
// 2 -> 4 -> 6
35+
while (l1 !== null && l2 !== null) {
36+
if (l1.val < l2.val) {
37+
current.next = l1; // 把小的添加到结果链表
38+
current = current.next; // 移动结果链表的指针
39+
l1 = l1.next; // 移动小的那个链表的指针
40+
} else {
41+
current.next = l2;
42+
current = current.next;
43+
l2 = l2.next;
44+
}
45+
}
46+
47+
if (l1 === null) {
48+
current.next = l2;
49+
} else {
50+
current.next = l1;
51+
}
52+
return dummyHead.next;
53+
}
54+
/**
55+
* Definition for singly-linked list.
56+
* function ListNode(val) {
57+
* this.val = val;
58+
* this.next = null;
59+
* }
60+
*/
61+
/**
62+
* @param {ListNode[]} lists
63+
* @return {ListNode}
64+
*/
65+
var mergeKLists = function(lists) {
66+
// 图参考: https://zhuanlan.zhihu.com/p/61796021
67+
if (lists.length === 0) return null;
68+
if (lists.length === 1) return lists[0];
69+
if (lists.length === 2) {
70+
return mergeTwoLists(lists[0], lists[1]);
71+
}
72+
73+
const mid = lists.length >> 1;
74+
const l1 = [];
75+
for (let i = 0; i < mid; i++) {
76+
l1[i] = lists[i];
77+
}
78+
79+
const l2 = [];
80+
for (let i = mid, j = 0; i < lists.length; i++, j++) {
81+
l2[j] = lists[i];
82+
}
83+
84+
return mergeTwoLists(mergeKLists(l1), mergeKLists(l2));
85+
};

Diff for: ‎236.lowest-common-ancestor-of-a-binary-tree.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* @lc app=leetcode id=236 lang=javascript
3+
*
4+
* [236] Lowest Common Ancestor of a Binary Tree
5+
*
6+
* https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/
7+
*
8+
* algorithms
9+
* Medium (35.63%)
10+
* Total Accepted: 267.3K
11+
* Total Submissions: 729.2K
12+
* Testcase Example: '[3,5,1,6,2,0,8,null,null,7,4]\n5\n1'
13+
*
14+
* Given a binary tree, find the lowest common ancestor (LCA) of two given
15+
* nodes in the tree.
16+
*
17+
* According to the definition of LCA on Wikipedia: “The lowest common ancestor
18+
* is defined between two nodes p and q as the lowest node in T that has both p
19+
* and q as descendants (where we allow a node to be a descendant of itself).”
20+
*
21+
* Given the following binary tree:  root = [3,5,1,6,2,0,8,null,null,7,4]
22+
*
23+
*
24+
*
25+
* Example 1:
26+
*
27+
*
28+
* Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
29+
* Output: 3
30+
* Explanation: The LCA of nodes 5 and 1 is 3.
31+
*
32+
*
33+
* Example 2:
34+
*
35+
*
36+
* Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
37+
* Output: 5
38+
* Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant
39+
* of itself according to the LCA definition.
40+
*
41+
*
42+
*
43+
*
44+
* Note:
45+
*
46+
*
47+
* All of the nodes' values will be unique.
48+
* p and q are different and both values will exist in the binary tree.
49+
*
50+
*
51+
*/
52+
/**
53+
* Definition for a binary tree node.
54+
* function TreeNode(val) {
55+
* this.val = val;
56+
* this.left = this.right = null;
57+
* }
58+
*/
59+
/**
60+
* @param {TreeNode} root
61+
* @param {TreeNode} p
62+
* @param {TreeNode} q
63+
* @return {TreeNode}
64+
*/
65+
var lowestCommonAncestor = function(root, p, q) {
66+
if (!root || root === p || root === q) return root;
67+
const left = lowestCommonAncestor(root.left, p, q);
68+
const right = lowestCommonAncestor(root.right, p, q);
69+
if (!left) return right; // 左子树找不到,返回右子树
70+
if (!right) return left; // 右子树找不到,返回左子树
71+
return root; // 左右子树分别有一个,则返回root
72+
};

Diff for: ‎238.product-of-array-except-self.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* @lc app=leetcode id=238 lang=javascript
3+
*
4+
* [238] Product of Array Except Self
5+
*
6+
* https://leetcode.com/problems/product-of-array-except-self/description/
7+
*
8+
* algorithms
9+
* Medium (53.97%)
10+
* Total Accepted: 246.5K
11+
* Total Submissions: 451.4K
12+
* Testcase Example: '[1,2,3,4]'
13+
*
14+
* Given an array nums of n integers where n > 1,  return an array output such
15+
* that output[i] is equal to the product of all the elements of nums except
16+
* nums[i].
17+
*
18+
* Example:
19+
*
20+
*
21+
* Input: [1,2,3,4]
22+
* Output: [24,12,8,6]
23+
*
24+
*
25+
* Note: Please solve it without division and in O(n).
26+
*
27+
* Follow up:
28+
* Could you solve it with constant space complexity? (The output array does
29+
* not count as extra space for the purpose of space complexity analysis.)
30+
*
31+
*/
32+
/**
33+
* @param {number[]} nums
34+
* @return {number[]}
35+
*/
36+
var productExceptSelf = function(nums) {
37+
const ret = [];
38+
39+
for (let i = 0, temp = 1; i < nums.length; i++) {
40+
ret[i] = temp;
41+
temp *= nums[i];
42+
}
43+
// 此时ret[i]存放的是前i个元素相乘的结果(不包含第i个)
44+
45+
// 如果没有上面的循环的话,
46+
// ret经过下面的循环会变成ret[i]存放的是后i个元素相乘的结果(不包含第i个)
47+
48+
// 我们的目标是ret[i]存放的所有数字相乘的结果(不包含第i个)
49+
50+
// 因此我们只需要对于上述的循环产生的ret[i]基础上运算即可
51+
for (let i = nums.length - 1, temp = 1; i >= 0; i--) {
52+
ret[i] *= temp;
53+
temp *= nums[i];
54+
}
55+
return ret;
56+
};

Diff for: ‎326.power-of-three.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* @lc app=leetcode id=326 lang=javascript
3+
*
4+
* [326] Power of Three
5+
*
6+
* https://leetcode.com/problems/power-of-three/description/
7+
*
8+
* algorithms
9+
* Easy (41.43%)
10+
* Total Accepted: 178.8K
11+
* Total Submissions: 430.4K
12+
* Testcase Example: '27'
13+
*
14+
* Given an integer, write a function to determine if it is a power of three.
15+
*
16+
* Example 1:
17+
*
18+
*
19+
* Input: 27
20+
* Output: true
21+
*
22+
*
23+
* Example 2:
24+
*
25+
*
26+
* Input: 0
27+
* Output: false
28+
*
29+
* Example 3:
30+
*
31+
*
32+
* Input: 9
33+
* Output: true
34+
*
35+
* Example 4:
36+
*
37+
*
38+
* Input: 45
39+
* Output: false
40+
*
41+
* Follow up:
42+
* Could you do it without using any loop / recursion?
43+
*/
44+
/**
45+
* @param {number} n
46+
* @return {boolean}
47+
*/
48+
var isPowerOfThree = function(n) {
49+
// let i = 0;
50+
// while(Math.pow(3, i) < n) {
51+
// i++;
52+
// }
53+
// return Math.pow(3, i) === n;
54+
55+
// 巧用整除
56+
return n > 0 && Math.pow(3, 19) % n === 0;
57+
};

Diff for: ‎334.increasing-triplet-subsequence.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* @lc app=leetcode id=334 lang=javascript
3+
*
4+
* [334] Increasing Triplet Subsequence
5+
*
6+
* https://leetcode.com/problems/increasing-triplet-subsequence/description/
7+
*
8+
* algorithms
9+
* Medium (39.47%)
10+
* Total Accepted: 89.6K
11+
* Total Submissions: 226.6K
12+
* Testcase Example: '[1,2,3,4,5]'
13+
*
14+
* Given an unsorted array return whether an increasing subsequence of length 3
15+
* exists or not in the array.
16+
*
17+
* Formally the function should:
18+
*
19+
* Return true if there exists i, j, k
20+
* such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return
21+
* false.
22+
*
23+
* Note: Your algorithm should run in O(n) time complexity and O(1) space
24+
* complexity.
25+
*
26+
*
27+
* Example 1:
28+
*
29+
*
30+
* Input: [1,2,3,4,5]
31+
* Output: true
32+
*
33+
*
34+
*
35+
* Example 2:
36+
*
37+
*
38+
* Input: [5,4,3,2,1]
39+
* Output: false
40+
*
41+
*
42+
*
43+
*/
44+
/**
45+
* @param {number[]} nums
46+
* @return {boolean}
47+
*/
48+
var increasingTriplet = function(nums) {
49+
if (nums.length < 3) return false;
50+
let n1 = Number.MAX_VALUE;
51+
let n2 = Number.MAX_VALUE;
52+
53+
for(let i = 0; i < nums.length; i++) {
54+
if (nums[i] <= n1) {
55+
n1 = nums[i]
56+
} else if (nums[i] <= n2) {
57+
n2 = nums[i]
58+
} else {
59+
return true;
60+
}
61+
}
62+
63+
return false;
64+
};
65+

Diff for: ‎344.reverse-string.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* @lc app=leetcode id=344 lang=javascript
3+
*
4+
* [344] Reverse String
5+
*
6+
* https://leetcode.com/problems/reverse-string/description/
7+
*
8+
* algorithms
9+
* Easy (62.81%)
10+
* Total Accepted: 409.9K
11+
* Total Submissions: 649.5K
12+
* Testcase Example: '["h","e","l","l","o"]'
13+
*
14+
* Write a function that reverses a string. The input string is given as an
15+
* array of characters char[].
16+
*
17+
* Do not allocate extra space for another array, you must do this by modifying
18+
* the input array in-place with O(1) extra memory.
19+
*
20+
* You may assume all the characters consist of printable ascii
21+
* characters.
22+
*
23+
*
24+
*
25+
*
26+
* Example 1:
27+
*
28+
*
29+
* Input: ["h","e","l","l","o"]
30+
* Output: ["o","l","l","e","h"]
31+
*
32+
*
33+
*
34+
* Example 2:
35+
*
36+
*
37+
* Input: ["H","a","n","n","a","h"]
38+
* Output: ["h","a","n","n","a","H"]
39+
*
40+
*
41+
*
42+
*
43+
*/
44+
/**
45+
* @param {character[]} s
46+
* @return {void} Do not return anything, modify s in-place instead.
47+
*/
48+
var reverseString = function(s) {
49+
for(let i = 0; i < s.length >> 1; i++) {
50+
const temp = s[i];
51+
s[i] = s[s.length - i - 1];
52+
s[s.length - i - 1] = temp;
53+
}
54+
};
55+

Diff for: ‎350.intersection-of-two-arrays-ii.js

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* @lc app=leetcode id=350 lang=javascript
3+
*
4+
* [350] Intersection of Two Arrays II
5+
*
6+
* https://leetcode.com/problems/intersection-of-two-arrays-ii/description/
7+
*
8+
* algorithms
9+
* Easy (46.84%)
10+
* Total Accepted: 185.1K
11+
* Total Submissions: 393.7K
12+
* Testcase Example: '[1,2,2,1]\n[2,2]'
13+
*
14+
* Given two arrays, write a function to compute their intersection.
15+
*
16+
* Example 1:
17+
*
18+
*
19+
* Input: nums1 = [1,2,2,1], nums2 = [2,2]
20+
* Output: [2,2]
21+
*
22+
*
23+
*
24+
* Example 2:
25+
*
26+
*
27+
* Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
28+
* Output: [4,9]
29+
*
30+
*
31+
* Note:
32+
*
33+
*
34+
* Each element in the result should appear as many times as it shows in both
35+
* arrays.
36+
* The result can be in any order.
37+
*
38+
*
39+
* Follow up:
40+
*
41+
*
42+
* What if the given array is already sorted? How would you optimize your
43+
* algorithm?
44+
* What if nums1's size is small compared to nums2's size? Which algorithm is
45+
* better?
46+
* What if elements of nums2 are stored on disk, and the memory is limited such
47+
* that you cannot load all elements into the memory at once?
48+
*
49+
*
50+
*/
51+
/**
52+
* @param {number[]} nums1
53+
* @param {number[]} nums2
54+
* @return {number[]}
55+
*/
56+
var intersect = function(nums1, nums2) {
57+
const res = [];
58+
59+
for (let i = 0; i < nums1.length; i++) {
60+
if (nums2.includes(nums1[i])) { // 这里我们对两个数组排序,然后二分查找, 时间复杂度nlogn
61+
nums2[nums2.indexOf(nums1[i])] = null;
62+
res.push(nums1[i]);
63+
}
64+
}
65+
66+
return res;
67+
};

Diff for: ‎387.first-unique-character-in-a-string.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* @lc app=leetcode id=387 lang=javascript
3+
*
4+
* [387] First Unique Character in a String
5+
*
6+
* https://leetcode.com/problems/first-unique-character-in-a-string/description/
7+
*
8+
* algorithms
9+
* Easy (49.29%)
10+
* Total Accepted: 255.6K
11+
* Total Submissions: 513.8K
12+
* Testcase Example: '"leetcode"'
13+
*
14+
*
15+
* Given a string, find the first non-repeating character in it and return it's
16+
* index. If it doesn't exist, return -1.
17+
*
18+
* Examples:
19+
*
20+
* s = "leetcode"
21+
* return 0.
22+
*
23+
* s = "loveleetcode",
24+
* return 2.
25+
*
26+
*
27+
*
28+
*
29+
* Note: You may assume the string contain only lowercase letters.
30+
*
31+
*/
32+
/**
33+
* @param {string} s
34+
* @return {number}
35+
*/
36+
var firstUniqChar = function(s) {
37+
for (let i = 0; i < s.length; i++) {
38+
if (s.indexOf(s[i]) === s.lastIndexOf(s[i])) {
39+
return i;
40+
}
41+
}
42+
return -1;
43+
};

Diff for: ‎README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
7575

7676
#### 简单难度
7777

78-
- [20. Valid Parentheses](./problems/20.validParentheses.md)
78+
- 🖊 [[20. Valid Parentheses](./problems/20.validParentheses.md)
7979
- [26.remove-duplicates-from-sorted-array](./problems/26.remove-duplicates-from-sorted-array.md)
8080
- 🆕 [88.merge-sorted-array](./problems/88.merge-sorted-array.md)
8181
- [136.single-number](./problems/136.single-number.md)
@@ -114,7 +114,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
114114
- [103.binary-tree-zigzag-level-order-traversal](./problems/103.binary-tree-zigzag-level-order-traversal.md)
115115
- [139.word-break](./problems/139.word-breakmd)
116116
- [144.binary-tree-preorder-traversal](./problems/144.binary-tree-preorder-traversal.md)
117-
- [150.evaluate-reverse-polish-notation](./problems/150.evaluate-reverse-polish-notation.md)
117+
- 🖊 [[150.evaluate-reverse-polish-notation](./problems/150.evaluate-reverse-polish-notation.md)
118118
- [199.binary-tree-right-side-view](./problems/199.binary-tree-right-side-view.md)
119119
- [201.bitwise-and-of-numbers-range](./problems/201.bitwise-and-of-numbers-range.md)
120120
- 🆕 [208.implement-trie-prefix-tree](./problems/208.implement-trie-prefix-tree.md)
@@ -142,9 +142,9 @@ leetcode 题解,记录自己的 leetcode 解题之路。
142142

143143
### 数据结构与算法的总结
144144

145-
- 🖊 [basic-data-structure](./thinkings/basic-data-structure.md)(草稿)
146-
- [binary-tree-traversal](./thinkings/binary-tree-traversal.md)
147-
- [dynamic-programming](./thinkings/dynamic-programming.md)
145+
- 🖊 [数据结构](./thinkings/basic-data-structure.md)(草稿)
146+
- 🖊 [[二叉树的遍历](./thinkings/binary-tree-traversal.md)
147+
- [动态规划](./thinkings/dynamic-programming.md)
148148
- [哈夫曼编码和游程编码](./thinkings/run-length-encode-and-huffman-encode.md)
149149
- [布隆过滤器](./thinkings/bloom-filter.md)
150150

Diff for: ‎problems/150.evaluate-reverse-polish-notation.md

+15-3
Original file line numberDiff line numberDiff line change
@@ -100,21 +100,28 @@ The given RPN expression is always valid. That means the expression would always
100100
* @return {number}
101101
*/
102102
var evalRPN = function(tokens) {
103+
// 这种算法的前提是 tokens是有效的,
104+
// 当然这由算法来保证
103105
const stack = [];
104106

105107
for (let index = 0; index < tokens.length; index++) {
106108
const token = tokens[index];
109+
// 对于运算数, 我们直接入栈
107110
if (!Number.isNaN(Number(token))) {
108111
stack.push(token);
109112
} else {
113+
// 遇到操作符,我们直接大胆运算,不用考虑算术优先级
114+
// 然后将运算结果入栈即可
115+
116+
// 当然如果题目进一步扩展,允许使用单目等其他运算符,我们的算法需要做微小的调整
110117
const a = Number(stack.pop());
111118
const b = Number(stack.pop());
112119
if (token === "*") {
113-
stack.push(a * b);
120+
stack.push(b * a);
114121
} else if (token === "/") {
115-
stack.push(b / a > 0 ? Math.floor(b / a) : Math.ceil(b / a));
122+
stack.push(b / a >> 0);
116123
} else if (token === "+") {
117-
stack.push(a + b);
124+
stack.push(b + a);
118125
} else if (token === "-") {
119126
stack.push(b - a);
120127
}
@@ -126,5 +133,10 @@ var evalRPN = function(tokens) {
126133

127134
```
128135

136+
## 扩展
137+
138+
逆波兰表达式中只改变运算符的顺序,并不会改变操作数的相对顺序,这是一个重要的性质。
139+
另外逆波兰表达式完全不关心操作符的优先级,这在中缀表达式中是做不到的,这很有趣,感兴趣的可以私下查找资料研究下为什么会这样。
140+
129141

130142

Diff for: ‎problems/20.validParentheses.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ Output: true
3636

3737
## 思路
3838

39+
关于这道题的思路,邓俊辉讲的非常好,没有看过的同学可以看一下, [视频地址](http://www.xuetangx.com/courses/course-v1:TsinghuaX+30240184+sp/courseware/ad1a23c053df4501a3facd66ef6ccfa9/8d6f450e7f7a445098ae1d507fda80f6/)
40+
3941
使用栈,遍历输入字符串
4042

4143
如果当前字符为左半边括号时,则将其压入栈中
@@ -54,6 +56,11 @@ Output: true
5456

5557
(图片来自: https://github.com/MisterBooo/LeetCodeAnimation)
5658

59+
> 值得注意的是,如果题目要求只有一种括号,那么我们其实可以使用更简洁,更省内存的方式 - 计数器来进行求解,而
60+
不必要使用栈。
61+
62+
> 事实上,这类问题还可以进一步扩展,我们可以去解析类似HTML等标记语法, 比如 <p></p> <body></body>
63+
5764
## 关键点解析
5865

5966
1. 栈的基本特点和操作
@@ -155,4 +162,7 @@ var isValid = function(s) {
155162

156163
return valid;
157164
};
158-
```
165+
```
166+
167+
## 扩展
168+
如果让你检查XML标签是否闭合如何检查, 更进一步如果要你实现一个简单的XML的解析器,应该怎么实现?

Diff for: ‎problems/279.perfect-squares.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ DP 的代码见代码区。
7878
```js
7979
for (let i = 1; i <= n; i++) {
8080
for (let j = 1; j * j <= i; j++) {
81-
// (dp[i]) 还是 不选(dp[i - j * j])
81+
// 不选(dp[i]) 还是 (dp[i - j * j])
8282
dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
8383
}
8484
}
@@ -130,7 +130,7 @@ var numSquares = function(n) {
130130
dp[0] = 0;
131131
for (let i = 1; i <= n; i++) {
132132
for (let j = 1; j * j <= i; j++) {
133-
// (dp[i]) 还是 不选(dp[i - j * j])
133+
// 不选(dp[i]) 还是 (dp[i - j * j])
134134
dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
135135
}
136136
}

Diff for: ‎thinkings/basic-data-structure.md

+69-1
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@
99
数据结构我们可以从逻辑上分为线性结构和非线性结果。线性结构有
1010
数组,栈,链表等, 非线性结构有树,图等。
1111

12+
> 其实我们可以称树为一种半线性结构。
13+
1214
需要注意的是,线性和非线性不代表存储结构是线性的还是非线性的,这两者没有任何关系,它只是一种逻辑上的划分。
1315
比如我们可以用数组去存储二叉树。
1416
### 数组
1517

1618
数组是最简单的数据结构了,很多地方都用到它。 比如有一个数据列表等,用它是再合适不过了。
1719
其实后面的数据结构很多都有数组的影子。
1820

21+
我们之后要讲的栈和队列其实都可以看成是一种`受限`的数组, 怎么个受限法呢?我们后面讨论。
22+
1923
我们来讲几个有趣的例子来加深大家对数组这种数据结构的理解。
2024
#### React Hooks
2125

@@ -69,6 +73,8 @@ React 将`如何确保组件内部hooks保存的状态之间的对应关系`这
6973
开发人员去保证,即你必须保证HOOKS的顺序严格一致,具体可以看React 官网关于 Hooks Rule 部分。
7074
### 队列
7175

76+
队列是一种受限的序列,它只能够操作队尾和队首,并且只能只能在队尾添加元素,在队首删除元素。
77+
7278
队列作为一种最常见的数据结构同样有着非常广泛的应用, 比如消息队列
7379

7480
> "队列"这个名称,可类比为现实生活中排队(不插队的那种)
@@ -107,6 +113,8 @@ React 将`如何确保组件内部hooks保存的状态之间的对应关系`这
107113
![basic-data-structure-queue-2](../assets/thinkings/basic-data-structure-queue-2.png)
108114

109115
###
116+
栈也是一种受限的序列,它只能够操作栈顶,不管入栈还是出栈,都是在栈顶操作。
117+
110118
在计算机科学中, 一个 栈(stack) 是一种抽象数据类型,用作表示元素的集合,具有两种主要操作:
111119

112120
push, 添加元素到栈的顶端(末尾);
@@ -155,6 +163,11 @@ foo();
155163
156164
> 社区中有很多“执行上下文中的scope指的是执行栈中父级声明的变量”说法,这是完全错误的, JS是词法作用域,scope指的是函数定义时候的父级,和执行没关系
157165
166+
167+
栈常见的应用有进制转换,括号匹配,栈混洗,中缀表达式(用的很少),后缀表达式(逆波兰表达式)等。
168+
169+
> 合法的栈混洗操作,其实和合法的括号匹配表达式之间存在着一一对应的关系,
170+
也就是说n个元素的栈混洗有多少种,n对括号的合法表达式就有多少种。感兴趣的可以查找相关资料
158171
### 链表
159172

160173
链表是一种最基本数据结构,熟练掌握链表的结构和常见操作是基础中的基础。
@@ -224,14 +237,66 @@ return, children, sibling也都是一个fiber,因此fiber看起来就是一个
224237
我目前也在写关于《从零开发react系列教程》中关于fiber架构的部分,如果你对具体实现感兴趣,欢迎关注。
225238
### 非线性结构
226239

240+
那么有了线性结果,我们为什么还需要非线性结果呢? 答案是为了高效地兼顾静态操作和动态操作。
241+
大家可以对照各种数据结构的各种操作的复杂度来直观感受一下。
227242
##
243+
树的应用同样非常广泛,小到文件系统,大到因特网,组织架构等都可以表示为树结构,
244+
而在我们前端眼中比较熟悉的DOM树也是一种树结构,而HTML作为一种DSL去描述这种树结构的具体表现形式。
245+
246+
树其实是一种特殊的``,是一种无环连通图,是一种极大无环图,也是一种极小连通图。
247+
248+
从另一个角度看,树是一种递归的数据结构。而且树的不同表示方法,比如不常用的`长子 + 兄弟`法,对于
249+
你理解树这种数据结构有着很大用处, 说是一种对树的本质的更深刻的理解也不为过。
250+
251+
树的基本算法有前中后序遍历和层次遍历,有的同学对前中后这三个分别具体表现的访问顺序比较模糊,
252+
其实当初我也是一样的,后面我学到了一点,你只需要记住:`所谓的前中后指的是根节点的位置,其他位置按照先左后右排列即可`
253+
比如前序遍历就是`根左右`, 中序就是`左根右`,后序就是`左右根`, 很简单吧?
254+
255+
我刚才提到了树是一种递归的数据结构,因此树的遍历算法使用递归去完成非常简单,
256+
幸运的是树的算法基本上都要依赖于树的遍历。 但是递归在计算机中的性能一直都有问题,
257+
因此掌握不那么容易理解的"命令式地迭代"遍历算法在某些情况下是有用的。
258+
259+
如果你使用迭代式方式去遍历的话,可以借助上面提到的``来进行,可以极大减少代码量。
260+
261+
> 如果使用栈来简化运算,由于栈是FILO的,因此一定要注意左右子树的推入顺序。
262+
263+
树的重要性质:
264+
265+
- 如果树有n个顶点,那么其就有n - 1条边,这说明了树的顶点数和边数是同阶的。
266+
- 任何一个节点到根节点存在`唯一`路径, 路径的长度为节点所处的深度
267+
268+
228269

229270
### 二叉树
230271

272+
二叉树是节点度数不超过二的树,是树的一种特殊子集,有趣的是二叉树这种被限制的树结构却能够表示和实现所有的树,
273+
它背后的原理正是`长子 + 兄弟`法,用邓老师的话说就是`二叉树是多叉树的特例,但在有根且有序时,其描述能力却足以覆盖后者`
274+
275+
> 实际上, 在你使用`长子 + 兄弟`法表示树的同时,进行45度角旋转即可。
276+
277+
相关算法:
278+
279+
- [94.binary-tree-inorder-traversal](../problems/94.binary-tree-inorder-traversal.md)
280+
- [102.binary-tree-level-order-traversal](../problems/102.binary-tree-level-order-traversal.md)
281+
- [103.binary-tree-zigzag-level-order-traversal](../problems/103.binary-tree-zigzag-level-order-traversal.md)
282+
- [144.binary-tree-preorder-traversal](../problems/144.binary-tree-preorder-traversal.md)
283+
- [145.binary-tree-postorder-traversal](../problems/145.binary-tree-postorder-traversal.md)
284+
- [199.binary-tree-right-side-view](../problems/199.binary-tree-right-side-view.md)
285+
286+
相关概念:
287+
288+
- 真二叉树
289+
290+
291+
另外我也专门开设了[二叉树的遍历](./binary-tree-traversal.md)章节, 具体细节和算法可以去那里查看。
231292
####
232293

233-
优先级队列
294+
堆其实是一种优先级队列,在很多语言都有对应的内置数据结构,很遗憾javascript没有这种原生的数据结构。
295+
不过这对我们理解和运用不会有影响。
296+
297+
相关算法:
234298

299+
- [295.find-median-from-data-stream](../problems/295.find-median-from-data-stream.md)
235300
#### 二叉查找树
236301

237302
### 平衡树
@@ -244,4 +309,7 @@ database engine
244309

245310
### 字典树(前缀树)
246311

312+
相关算法:
313+
314+
- [208.implement-trie-prefix-tree](../problems/208.implement-trie-prefix-tree.md)
247315
##

Diff for: ‎thinkings/binary-tree-traversal.md

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ BFS 的关键点在于如何记录每一层次是否遍历完成, 我们可以
3838

3939
总结: 典型的递归数据结构,典型的用栈来简化操作的算法。
4040

41+
其实从宏观上表现为:`自顶向下依次访问左侧链,然后自底向上依次访问右侧链`
42+
如果从这个角度出发去写的话,算法就不一样了。从上向下我们可以直接递归访问即可,从下向上我们只需要借助栈也可以轻易做到。
43+
这种思路解题有点像我总结过的一个解题思路`backtrack` - 回溯法。这种思路有一个好处就是
44+
可以`统一三种遍历的思路`.
45+
4146
## 中序遍历
4247

4348
相关问题[94.binary-tree-inorder-traversal](../problems/94.binary-tree-inorder-traversal.md)

Diff for: ‎todo/candidates/324.wiggle-sort-ii.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* @lc app=leetcode id=324 lang=javascript
3+
*
4+
* [324] Wiggle Sort II
5+
*
6+
* https://leetcode.com/problems/wiggle-sort-ii/description/
7+
*
8+
* algorithms
9+
* Medium (27.53%)
10+
* Total Accepted: 57.5K
11+
* Total Submissions: 206.9K
12+
* Testcase Example: '[1,5,1,1,6,4]'
13+
*
14+
* Given an unsorted array nums, reorder it such that nums[0] < nums[1] >
15+
* nums[2] < nums[3]....
16+
*
17+
* Example 1:
18+
*
19+
*
20+
* Input: nums = [1, 5, 1, 1, 6, 4]
21+
* Output: One possible answer is [1, 4, 1, 5, 1, 6].
22+
*
23+
* Example 2:
24+
*
25+
*
26+
* Input: nums = [1, 3, 2, 2, 3, 1]
27+
* Output: One possible answer is [2, 3, 1, 3, 1, 2].
28+
*
29+
* Note:
30+
* You may assume all input has valid answer.
31+
*
32+
* Follow Up:
33+
* Can you do it in O(n) time and/or in-place with O(1) extra space?
34+
*/
35+
/**
36+
* @param {number[]} nums
37+
* @return {void} Do not return anything, modify nums in-place instead.
38+
*/
39+
var wiggleSort = function(nums) {
40+
for(let i = 0; i < nums.length; i++) {}
41+
};
42+

0 commit comments

Comments
 (0)
Please sign in to comment.