├── .gitattributes ├── .gitignore ├── .vscode └── settings.json ├── Basic200 ├── BinarySearch │ ├── LC278. First Bad Version.md │ ├── LC287. Find the Duplicate Number.md │ ├── LC34. Find First and Last Position of Element in Sorted Array.md │ ├── LC528. Random Pick with Weight.md │ ├── LC540. Single Element in a Sorted Array.md │ ├── LC69. Sqrt(x).md │ └── LC719. Find K-th Smallest Pair Distance.md ├── BinaryTree │ ├── LC105. Construct Binary Tree from Preorder and Inorder Traversal.md │ ├── LC106. Construct Binary Tree from Inorder and Postorder Traversal.md │ ├── LC110. Balanced Binary Tree.md │ ├── LC112. Path Sum.md │ ├── LC116. Populating Next Right Pointers in Each Node.md │ ├── LC124. Binary Tree Maximum Path Sum.md │ ├── LC1372. Longest ZigZag Path in a Binary Tree.md │ ├── LC297. Serialize and Deserialize Binary Tree.md │ ├── LC449. Serialize and Deserialize BST.md │ ├── LC513. Find Bottom Left Tree Value.md │ ├── LC654. Maximum Binary Tree.md │ ├── LC662. Maximum Width of Binary Tree.md │ ├── LC863. All Nodes Distance K in Binary Tree.md │ └── LC889. Construct Binary Tree from Preorder and Postorder Traversal.md ├── DP │ ├── LC10. Regular Expression Matching.md │ ├── LC32. Longest Valid Parentheses.md │ ├── LC42. Trapping Rain Water.md │ ├── LC44. Wildcard Matching.md │ ├── LC5. Longest Palindromic Substring.md │ ├── LC53. Maximum Subarray.md │ ├── LC62. Unique Paths.md │ ├── LC63. Unique Paths II.md │ └── LC64. Minimum Path Sum.md ├── G │ └── LC 690. Employee Importance.md ├── Heap │ ├── LC1439. Find the Kth Smallest Sum of a Matrix With Sorted Rows.md │ ├── LC1488. Avoid Flood in The City.md │ ├── LC1642. Furthest Building You Can Reach.md │ ├── LC1675. Minimize Deviation in Array.md │ ├── LC264. Ugly Number II.md │ ├── LC295. Find Median from Data Stream.md │ ├── LC632. Smallest Range Covering Elements from K Lists.md │ ├── LC743. Network Delay Time.md │ ├── LC787. Cheapest Flights Within K Stops.md │ ├── LC871. Minimum Number of Refueling Stops.md │ └── Template.md ├── LC10 正则表达式匹配.md ├── LC101. Symmetric Tree.md ├── LC102. Binary Tree Level Order Traversal.md ├── LC103. Binary Tree Zigzag Level Order Traversal.md ├── LC105. Construct Binary Tree from Preorder and Inorder Traversal.md ├── LC107. Binary Tree Level Order Traversal II.md ├── LC108. Convert Sorted Array to Binary Search Tree.md ├── LC11.md ├── LC113. Path Sum II.md ├── LC116. Populating Next Right Pointers in Each Node.md ├── LC12. Integer to Roman.md ├── LC121. Best Time to Buy and Sell Stock.md ├── LC122. Best Time to Buy and Sell Stock II.md ├── LC124. Binary Tree Maximum Path Sum.md ├── LC125. Valid Palindrome.md ├── LC126. Word Ladder II.md ├── LC127. Word Ladder.md ├── LC128. Longest Consecutive Sequence.md ├── LC13. Roman to Integer.md ├── LC13.md ├── LC130. Surrounded Regions.md ├── LC131. Palindrome Partitioning.md ├── LC132. Palindrome Partitioning II.md ├── LC134. Gas Station.md ├── LC135. Candy.md ├── LC136. Single Number.md ├── LC1371. Find the Longest Substring Containing Vowels in Even Counts.md ├── LC138. Copy List with Random Pointer.md ├── LC14.md ├── LC140. Word Break II.md ├── LC141. Linked List Cycle.md ├── LC142. Linked List Cycle II.md ├── LC145. Binary Tree Postorder Traversal.md ├── LC146. LRU Cache.md ├── LC147. Insertion Sort List.md ├── LC1492. The kth Factor of n.md ├── LC15.md ├── LC152. Maximum Product Subarray.md ├── LC153. Find Minimum in Rotated Sorted Array.md ├── LC155. Min Stack.md ├── LC16. 3Sum Closest.md ├── LC162. Find Peak Element.md ├── LC163. Missing Ranges.md ├── LC169. Majority Element.md ├── LC17. Letter Combinations of a Phone Number.md ├── LC171. Excel Sheet Column Number.md ├── LC18. 4Sum.md ├── LC1851. Minimum Interval to Include Each Query.md ├── LC189. Rotate Array.md ├── LC19. Remove Nth Node From End of List.md ├── LC199. Binary Tree Right Side View.md ├── LC2.md ├── LC20.md ├── LC200. Number of Islands.md ├── LC204. Count Primes.md ├── LC206. Reverse Linked List.md ├── LC21.md ├── LC215. Kth Largest Element in an Array.md ├── LC22.md ├── LC227. Basic Calculator II.md ├── LC23. Merge k Sorted Lists.md ├── LC234. Palindrome Linked List.md ├── LC237. Delete Node in a Linked List.md ├── LC240. Search a 2D Matrix II.md ├── LC257. Binary Tree Paths.md ├── LC283. Move Zeroes.md ├── LC29. Divide Two Integers.md ├── LC31. Next Permutation.md ├── LC32. Longest Valid Parentheses.md ├── LC33. Search in Rotated Sorted Array.md ├── LC36.md ├── LC37. Sudoku Solver.md ├── LC38. Count and Say.md ├── LC4. Median of Two Sorted Arrays.md ├── LC41. First Missing Positive.md ├── LC42. Trapping Rain Water.md ├── LC43. Multiply Strings.md ├── LC44. Wildcard Matching.md ├── LC45. Jump Game II.md ├── LC460. LFU Cache.md ├── LC48. Rotate Image.md ├── LC49.md ├── LC5 最长回文.md ├── LC50. Pow(x, n).md ├── LC51. N-Queens.md ├── LC52. N-Queens II.md ├── LC54. Spiral Matrix.md ├── LC55. Jump Game.md ├── LC56. Merge Intervals.md ├── LC57. Insert Interval.md ├── LC5773. Maximum Value after Insertion.md ├── LC58. Length of Last Word.md ├── LC59. Spiral Matrix II.md ├── LC6. ZigZag Conversion.md ├── LC60. Permutation Sequence.md ├── LC61. Rotate List.md ├── LC645. Set Mismatch.md ├── LC66. Plus One.md ├── LC7.md ├── LC70. Climbing Stairs.md ├── LC71. Simplify Path.md ├── LC73. Set Matrix Zeroes.md ├── LC74. Search a 2D Matrix.md ├── LC75. Sort Colors.md ├── LC77. Combinations.md ├── LC79. Word Search.md ├── LC8.md ├── LC81. Search in Rotated Sorted Array II.md ├── LC815. Bus Routes.md ├── LC83. Remove Duplicates from Sorted List.md ├── LC84. Largest Rectangle in Histogram.md ├── LC86. Partition List.md ├── LC875. Koko Eating Bananas.md ├── LC88. Merge Sorted Array.md ├── LC9.md ├── LC94. Binary Tree Inorder Traversal.md ├── LC96. Unique Binary Search Trees.md ├── LC98. Validate Binary Search Tree.md ├── MonotonicStack │ ├── LC316. Remove Duplicate Letters.md │ ├── LC402. Remove K Digits.md │ ├── LC42. Trapping Rain Water.md │ ├── LC739. Daily Temperatures.md │ └── LC84. Largest Rectangle in Histogram.md ├── T │ ├── LC1136. Parallel Courses.md │ ├── LC20. Valid Parentheses.md │ ├── LC207. Course Schedule.md │ ├── LC210. Course Schedule II.md │ ├── LC227. Basic Calculator II.md │ ├── LC419. Battleships in a Board.md │ ├── LC65. Valid Number.md │ ├── LC68. Text Justification.md │ ├── LC695. Max Area of Island.md │ └── LC841. Keys and Rooms.md ├── TODOLC50. Pow(x, n).md ├── Trie │ ├── LC208. Implement Trie (Prefix Tree).md │ ├── LC211. Design Add and Search Words Data Structure.md │ ├── LC212. Word Search II.md │ └── LC421. Maximum XOR of Two Numbers in an Array.md ├── TwoPointers │ ├── LC209. Minimum Size Subarray Sum.md │ ├── LC3. Longest Substring Without Repeating Characters.md │ ├── LC438. Find All Anagrams in a String.md │ ├── LC76. Minimum Window Substring.md │ ├── LC904. Fruit Into Baskets.md │ └── Template.md ├── UnionFind │ ├── LC200. Number of Islands.md │ ├── LC399. Evaluate Division.md │ ├── LC547. Number of Provinces.md │ └── LC684. Redundant Connection.md ├── 剑指 Offer 03. 数组中重复的数字.md ├── 剑指 Offer 50. 第一个只出现一次的字符.md └── 面试题 10.03. Search Rotate Array LCCI.md ├── Basic200II ├── BFS & DFS │ ├── LC127. Word Ladder.md │ ├── LC5791. Count Sub Islands.md │ ├── LC752. Open the Lock.md │ ├── LC773. Sliding Puzzle.md │ └── LC994. Rotting Oranges.md ├── BinarySearch │ ├── LC1011. Capacity To Ship Packages Within D Days.md │ ├── LC153. Find Minimum in Rotated Sorted Array.md │ ├── LC154. Find Minimum in Rotated Sorted Array II.md │ ├── LC162. Find Peak Element.md │ ├── LC315. Count of Smaller Numbers After Self.md │ ├── LC35. Search Insert Position.md │ ├── LC475. Heaters.md │ ├── LC528. 按权重随机选择.md │ ├── LC719. Find K-th Smallest Pair Distance.md │ ├── LC778. Swim in Rising Water.md │ └── LC875. Koko Eating Bananas.md ├── DP │ ├── 背包 │ │ ├── LC279. Perfect Squares.md │ │ └── LC416. Partition Equal Subset Sum.md │ └── 路径问题 │ │ ├── LC120. Triangle.md │ │ ├── LC1289. Minimum Falling Path Sum II.md │ │ ├── LC1301. Number of Paths with Max Score.md │ │ ├── LC1575. 统计所有可行路径.md │ │ ├── LC576. 出界的路径数.md │ │ ├── LC62. Unique Paths.md │ │ ├── LC63. Unique Paths II.md │ │ ├── LC64. Minimum Path Sum.md │ │ ├── LC668马在棋盘上的概率 & LC576.md │ │ ├── LC91. Decode Ways.md │ │ └── LC931. Minimum Falling Path Sum.md ├── DynamicProgramming │ ├── DP线性 │ │ ├── LC152. Maximum Product Subarray.md │ │ ├── LC300. Longest Increasing Subsequence.md │ │ ├── LC354. Russian Doll Envelopes.md │ │ ├── LC518. Coin Change 2.md │ │ ├── LC53. Maximum Subarray.md │ │ ├── LC673. Number of Longest Increasing Subsequence.md │ │ ├── LC918. Maximum Sum Circular Subarray.md │ │ └── 打家劫舍 │ │ │ ├── LC198. House Robber.md │ │ │ ├── LC213. House Robber II.md │ │ │ └── LC740. Delete and Earn.md │ ├── LC10. Regular Expression Matching.md │ ├── LC1035. Uncrossed Lines.md │ ├── LC1143. Longest Common Subsequence.md │ ├── LC139. Word Break.md │ ├── LC140. Word Break II.md │ ├── LC174. Dungeon Game.md │ ├── LC198. House Robber.md │ ├── LC292. Nim Game.md │ ├── LC3. Longest Substring Without Repeating Characters.md │ ├── LC312. Burst Balloons.md │ ├── LC322. Coin Change.md │ ├── LC337. House Robber III.md │ ├── LC357. Count Numbers with Unique Digits.md │ ├── LC416. Partition Equal Subset Sum.md │ ├── LC435. Non-overlapping Intervals.md │ ├── LC44. Wildcard Matching.md │ ├── LC516. Longest Palindromic Subsequence.md │ ├── LC62. Unique Paths.md │ ├── LC63. Unique Paths II.md │ ├── LC646. Maximum Length of Pair Chain.md │ ├── LC70. Climbing Stairs.md │ ├── LC718. Maximum Length of Repeated Subarray.md │ ├── LC72. Edit Distance.md │ ├── LC808. Soup Servings.md │ ├── LC837. New 21 Game.md │ ├── LC87. Scramble String.md │ ├── Template.md │ └── 面试题 17.13. 恢复空格.md ├── G │ ├── LC1048. Longest String Chain.md │ ├── LC1102. Path With Maximum Minimum Value.md │ ├── LC1110. Delete Nodes And Return Forest.md │ ├── LC1293. Shortest Path in a Grid with Obstacles Elimination.md │ ├── LC1368. Minimum Cost to Make at Least One Valid Path in a Grid.md │ ├── LC1423. Maximum Points You Can Obtain from Cards.md │ ├── LC1499. Max Value of Equation.md │ ├── LC1509. Minimum Difference Between Largest and Smallest Value in Three Moves.md │ ├── LC1525. Number of Good Ways to Split a String.md │ ├── LC1526. Minimum Number of Increments on Subarrays to Form a Target Array.md │ ├── LC1610. Maximum Number of Visible Points.md │ ├── LC359. Logger Rate Limiter.md │ ├── LC648. Replace Words.md │ ├── LC652. Find Duplicate Subtrees.md │ ├── LC690. Employee Importance.md │ └── LC853. Car Fleet.md ├── Graph&Topo │ ├── Best Currency Path.md │ ├── LC1135. Connecting Cities With Minimum Cost.md │ ├── LC133. Clone Graph.md │ ├── LC1462. Course Schedule IV.md │ ├── LC1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree.md │ ├── LC1584. Min Cost to Connect All Points.md │ ├── LC1631. Path With Minimum Effort.md │ ├── LC207. Course Schedule.md │ ├── LC210. Course Schedule II.md │ ├── LC261. Graph Valid Tree.md │ ├── LC329. Longest Increasing Path in a Matrix.md │ ├── LC743. Network Delay Time.md │ ├── LC785. Is Graph Bipartite.md │ ├── LC802. Find Eventual Safe States.md │ ├── LC815. Bus Routes.md │ ├── LC882. Reachable Nodes In Subdivided Graph.md │ └── LC886. Possible Bipartition.md ├── LC100. Same Tree.md ├── LC1004. Max Consecutive Ones III.md ├── LC101. Symmetric Tree.md ├── LC102. Binary Tree Level Order Traversal.md ├── LC103. Binary Tree Zigzag Level Order Traversal.md ├── LC104. Maximum Depth of Binary Tree.md ├── LC105. Construct Binary Tree from Preorder and Inorder Traversal.md ├── LC1052. Grumpy Bookstore Owner.md ├── LC106. Construct Binary Tree from Inorder and Postorder Traversal.md ├── LC107. Binary Tree Level Order Traversal II.md ├── LC108. Convert Sorted Array to Binary Search Tree.md ├── LC109. Convert Sorted List to Binary Search Tree.md ├── LC11. Container With Most Water.md ├── LC110. Balanced Binary Tree.md ├── LC1109. Corporate Flight Bookings.md ├── LC111. Minimum Depth of Binary Tree.md ├── LC112. Path Sum.md ├── LC113. Path Sum II.md ├── LC114. Flatten Binary Tree to Linked List.md ├── LC115. Distinct Subsequences.md ├── LC116. Populating Next Right Pointers in Each Node.md ├── LC117. Populating Next Right Pointers in Each Node II.md ├── LC118. Pascal's Triangle.md ├── LC119. Pascal's Triangle II.md ├── LC120. Triangle.md ├── LC121. Best Time to Buy and Sell Stock.md ├── LC122. Best Time to Buy and Sell Stock II.md ├── LC123. Best Time to Buy and Sell Stock III.md ├── LC124. Binary Tree Maximum Path Sum.md ├── LC126. Word Ladder II.md ├── LC128. Longest Consecutive Sequence.md ├── LC129. Sum Root to Leaf Numbers.md ├── LC130. Surrounded Regions.md ├── LC131. Palindrome Partitioning.md ├── LC1319. Number of Operations to Make Network Connected.md ├── LC132. Palindrome Partitioning II.md ├── LC133. Clone Graph.md ├── LC134. Gas Station.md ├── LC138. Copy List with Random Pointer.md ├── LC14. Longest Common Prefix.md ├── LC141. Linked List Cycle.md ├── LC142. Linked List Cycle II.md ├── LC1423. Maximum Points You Can Obtain from Cards.md ├── LC143. Reorder List.md ├── LC144. Binary Tree Preorder Traversal.md ├── LC145. Binary Tree Postorder Traversal.md ├── LC146. LRU Cache.md ├── LC147. Insertion Sort List.md ├── LC148. Sort List.md ├── LC15. 3Sum.md ├── LC150. Evaluate Reverse Polish Notation.md ├── LC151. Reverse Words in a String.md ├── LC155. Min Stack.md ├── LC156. Binary Tree Upside Down.md ├── LC159. Longest Substring with At Most Two Distinct Characters.md ├── LC16. 3Sum Closest.md ├── LC1600. Throne Inheritance.md ├── LC161. One Edit Distance.md ├── LC165. Compare Version Numbers.md ├── LC167. Two Sum II - Input array is sorted.md ├── LC168. Excel Sheet Column Title.md ├── LC169. Majority Element.md ├── LC17. Letter Combinations of a Phone Number.md ├── LC171. Excel Sheet Column Number.md ├── LC1723. Find Minimum Time to Finish All Jobs.md ├── LC173. Binary Search Tree Iterator.md ├── LC1755. Closest Subsequence Sum.md ├── LC179. Largest Number.md ├── LC18. 4Sum.md ├── LC1838. Frequency of the Most Frequent Element.md ├── LC186. Reverse Words in a String II.md ├── LC187. Repeated DNA Sequences.md ├── LC189. Rotate Array.md ├── LC19. Remove Nth Node From End of List.md ├── LC1904. The Number of Full Rounds You Have Played.md ├── LC199. Binary Tree Right Side View.md ├── LC2. Add Two Numbers.md ├── LC20. Valid Parentheses.md ├── LC200. Number of Islands.md ├── LC202. Happy Number.md ├── LC203. Remove Linked List Elements.md ├── LC206. Reverse Linked List.md ├── LC21. Merge Two Sorted Lists.md ├── LC214. Shortest Palindrome.md ├── LC215. Kth Largest Element in an Array.md ├── LC216. Combination Sum III.md ├── LC218. The Skyline Problem.md ├── LC219. Contains Duplicate II.md ├── LC22. Generate Parentheses.md ├── LC220. Contains Duplicate III.md ├── LC221. Maximal Square.md ├── LC222. Count Complete Tree Nodes.md ├── LC224. Basic Calculator.md ├── LC226. Invert Binary Tree.md ├── LC227. Basic Calculator II.md ├── LC229. Majority Element II.md ├── LC23. Merge k Sorted Lists.md ├── LC230. Kth Smallest Element in a BST.md ├── LC234. Palindrome Linked List.md ├── LC235. Lowest Common Ancestor of a Binary Search Tree.md ├── LC236. Lowest Common Ancestor of a Binary Tree.md ├── LC237. Delete Node in a Linked List.md ├── LC239. Sliding Window Maximum.md ├── LC24. Swap Nodes in Pairs.md ├── LC240. Search a 2D Matrix II.md ├── LC241. Different Ways to Add Parentheses.md ├── LC244. Shortest Word Distance II.md ├── LC25. Reverse Nodes in k-Group.md ├── LC250. Count Univalue Subtrees.md ├── LC251. Flatten 2D Vector.md ├── LC252. Meeting Rooms.md ├── LC253. Meeting Rooms II.md ├── LC254. Factor Combinations.md ├── LC255. Verify Preorder Sequence in Binary Search Tree.md ├── LC257. Binary Tree Paths.md ├── LC259. 3Sum Smaller.md ├── LC26. Remove Duplicates from Sorted Array.md ├── LC269. Alien Dictionary.md ├── LC27. Remove Element.md ├── LC270. Closest Binary Search Tree Value.md ├── LC272. Closest Binary Search Tree Value II.md ├── LC274. H-Index.md ├── LC277. Find the Celebrity.md ├── LC28. Implement strStr().md ├── LC282. Expression Add Operators.md ├── LC283. Move Zeroes.md ├── LC285. Inorder Successor in BST.md ├── LC287. Find the Duplicate Number.md ├── LC29. Divide Two Integers.md ├── LC290. Word Pattern.md ├── LC291. Word Pattern II.md ├── LC295. Find Median from Data Stream.md ├── LC296. Best Meeting Point.md ├── LC297. Serialize and Deserialize Binary Tree.md ├── LC298. Binary Tree Longest Consecutive Sequence.md ├── LC30. Substring with Concatenation of All Words.md ├── LC301. Remove Invalid Parentheses.md ├── LC305. Number of Islands II.md ├── LC31. Next Permutation.md ├── LC312. Burst Balloons.md ├── LC315. Count of Smaller Numbers After Self.md ├── LC32. Longest Valid Parentheses.md ├── LC327. Count of Range Sum.md ├── LC328. Odd Even Linked List.md ├── LC33. Search in Rotated Sorted Array.md ├── LC336. Palindrome Pairs.md ├── LC34. Find First and Last Position of Element in Sorted Array.md ├── LC347. Top K Frequent Elements.md ├── LC352. Data Stream as Disjoint Intervals.md ├── LC36. Valid Sudoku.md ├── LC38. Count and Say.md ├── LC380. Insert Delete GetRandom O(1).md ├── LC387. First Unique Character in a String.md ├── LC39. Combination Sum.md ├── LC395. Longest Substring with At Least K Repeating Characters.md ├── LC4. Median of Two Sorted Arrays.md ├── LC40. Combination Sum II.md ├── LC403. Frog Jump.md ├── LC41. First Missing Positive.md ├── LC42. Trapping Rain Water.md ├── LC424. Longest Repeating Character Replacement.md ├── LC426. Convert Binary Search Tree to Sorted Doubly Linked List.md ├── LC43. Multiply Strings.md ├── LC445. Add Two Numbers II.md ├── LC448. Find All Numbers Disappeared in an Array.md ├── LC45. Jump Game II.md ├── LC456. 132 Pattern.md ├── LC46. Permutations.md ├── LC47. Permutations II.md ├── LC49. Group Anagrams.md ├── LC50. Pow(x, n).md ├── LC51. N-Queens.md ├── LC54. Spiral Matrix.md ├── LC547. Number of Provinces.md ├── LC55. Jump Game.md ├── LC56. Merge Intervals.md ├── LC57. Insert Interval.md ├── LC5782. Maximum Alternating Subsequence Sum.md ├── LC5815. Maximum Number of Points with Cost.md ├── LC59. Spiral Matrix II.md ├── LC6. ZigZag Conversion.md ├── LC60. Permutation Sequence.md ├── LC61. Rotate List.md ├── LC65. Valid Number.md ├── LC66. Plus One.md ├── LC679. 24 Game.md ├── LC68. Text Justification.md ├── LC684. Redundant Connection.md ├── LC69. Sqrt(x).md ├── LC698. Partition to K Equal Sum Subsets.md ├── LC7. Reverse Integer.md ├── LC707. Design Linked List.md ├── LC71. Simplify Path.md ├── LC721. Accounts Merge.md ├── LC73. Set Matrix Zeroes.md ├── LC74. Search a 2D Matrix.md ├── LC75. Sort Colors.md ├── LC76. Minimum Window Substring.md ├── LC77. Combinations.md ├── LC772. Basic Calculator III.md ├── LC78. Subsets.md ├── LC79. Word Search.md ├── LC8. String to Integer (atoi).md ├── LC80. Remove Duplicates from Sorted Array II.md ├── LC81. Search in Rotated Sorted Array II.md ├── LC82. Remove Duplicates from Sorted List II.md ├── LC83. Remove Duplicates from Sorted List.md ├── LC84. Largest Rectangle in Histogram.md ├── LC843. Guess the Word.md ├── LC85. Maximal Rectangle.md ├── LC86. Partition List.md ├── LC88. Merge Sorted Array.md ├── LC9. Palindrome Number.md ├── LC90. Subsets II.md ├── LC92. Reverse Linked List II.md ├── LC93. Restore IP Addresses.md ├── LC94. Binary Tree Inorder Traversal.md ├── LC95. Unique Binary Search Trees II.md ├── LC959. Regions Cut By Slashes.md ├── LC96. Unique Binary Search Trees.md ├── LC97. Interleaving String.md ├── LC974. Subarray Sums Divisible by K.md ├── LC98. Validate Binary Search Tree.md ├── LC99. Recover Binary Search Tree.md ├── Prefix │ ├── LC1893. Check if All the Integers in a Range Are Covered.md │ └── LC238. Product of Array Except Self.md ├── T │ ├── LC1136. Parallel Courses.md │ ├── LC1197. Minimum Knight Moves.md │ ├── LC1500. Design a File Sharing System.md │ ├── LC419. Battleships in a Board.md │ ├── LC460. LFU Cache.md │ ├── LC723. Candy Crush.md │ ├── LC767. Reorganize String.md │ ├── LC841. Keys and Rooms.md │ └── LC977. Squares of a Sorted Array.md ├── Trie │ ├── LC208. Implement Trie (Prefix Tree).md │ ├── LC211. Design Add and Search Words Data Structure.md │ ├── LC212. Word Search II.md │ ├── LC642. Design Search Autocomplete System.md │ └── LC692. Top K Frequent Words.md ├── UnionFind │ └── LC765. Couples Holding Hands.md ├── WP │ ├── LC150. Evaluate Reverse Polish Notation.md │ ├── LC152. Maximum Product Subarray.md │ ├── LC226. Invert Binary Tree.md │ ├── LC341. Flatten Nested List Iterator.md │ ├── LC438. Find All Anagrams in a String.md │ ├── LC443. String Compression.md │ ├── LC56. Merge Intervals.md │ ├── LC65. Valid Number.md │ ├── LC68. Text Justification.md │ ├── LC76. Minimum Window Substring.md │ └── Template.md ├── 剑指 │ ├── review.md │ ├── 剑指 Offer 03. 数组中重复的数字.md │ ├── 剑指 Offer 04. 二维数组中的查找.md │ ├── 剑指 Offer 06. 从尾到头打印链表.md │ ├── 剑指 Offer 11. 旋转数组的最小数字.md │ ├── 剑指 Offer 22. 链表中倒数第k个节点.md │ ├── 剑指 Offer 25. 合并两个排序的链表.md │ ├── 剑指 Offer 27. 二叉树的镜像.md │ ├── 剑指 Offer 29. 顺时针打印矩阵.md │ ├── 剑指 Offer 34. 二叉树中和为某一值的路径.md │ ├── 剑指 Offer 40. 最小的k个数.md │ ├── 剑指 Offer 42. 连续子数组的最大和.md │ ├── 剑指 Offer 51. 数组中的逆序对.md │ └── 剑指 Offer 55 - I. 二叉树的深度.md ├── 面试题 02.04. 分割链表.md ├── 面试题 02.05. Sum Lists LCCI.md ├── 面试题 08.06. Hanota LCCI.md ├── 面试题 08.09. 括号.md ├── 面试题 16.19. 水域大小.md └── 面试题 17.19. 消失的两个数字.md ├── JavaScript ├── JS.md ├── promise.js ├── promise.md └── readme.md ├── LeetCodeHeapAPI.md ├── NotesBasedOnCategories ├── Binary Search Updated.md ├── Binary Search.md ├── Binary Tree.md ├── Bitwise.md ├── DP LeetCode.md ├── DP学习宫水.md ├── Divede and Conqure.md ├── Dynamic Programming.md ├── Graph.md ├── Hashtable.md ├── Heap.md ├── Monotonic Queue.md ├── Probability Permutation Combination.md ├── Search BFS DFS Backtrack.md ├── Sortings Methods.md ├── Topological.md ├── Trie.md ├── Two Pointers and Sliding Window.md ├── Union Find.md ├── preSum and Prefix.md ├── readme.md ├── 二分法模板.md ├── 二维图快速编码.md ├── 划重点.md ├── 双指针.md ├── 差分数组.md ├── 快速幂.md ├── 排列组合.md ├── 数学知识.md ├── 旋转matrix.md ├── 笔记LinkedList.md └── 符号和英文名.md ├── README.md ├── Template.md ├── TemplateLCPP5.md ├── archive_letcodepp2 ├── W1ArrayStack │ ├── W1D1LC66.md │ ├── W1D2LC821.md │ ├── W1D3LC1381.md │ ├── W1D4LC394.md │ ├── W1D5LC232.md │ ├── W1D6LC768NR.md │ └── notes.md ├── W2LinkedList │ ├── D10LC142.md │ ├── D11LC160.md │ ├── D12LC146.md │ ├── D7LC24.md │ ├── D8LC61.md │ ├── D9LC109.md │ └── notes.md ├── W3Trees │ ├── D13LC104.md │ ├── D14LC100.md │ ├── D15LC129.md │ ├── D16LC513.md │ ├── D17LC297.md │ ├── D18 NEEDTODO.md │ ├── TreeStudyNotes.md │ └── notes.md ├── W4Hash │ ├── D19LC1.md │ ├── D20LC347.md │ ├── D21LC447.md │ ├── D22LC3.md │ ├── D23LC30.md │ ├── D24TODO.md │ ├── DuoRenMeeting.js │ ├── MinHeapMaxHeap.md │ └── hashNotes.md ├── W5TwoPointers │ ├── D25LC35.md │ ├── D26LC74.md │ ├── D27LC26.md │ ├── D28LC867.md │ ├── D29LC1052.md │ └── D30LC239.md ├── W6D34BinaryTree │ ├── LC144PreorderTraversal.md │ ├── LC145PostorderTraversal.md │ ├── LC94InorderTraversal.md │ └── binaryTrees.md ├── W6D35ReverseLinkedList │ ├── LC206ReversedLinkedList.md │ ├── LC92ReverseLinkedListII.md │ └── TODOLC25.md ├── W6D36位运算 │ └── LC78Subsets.md ├── W6D38Stack │ ├── LC20.md │ └── LC32.md ├── W6D39Design │ └── 剑指09.md └── otherQs │ ├── LC150 Ruby.md │ └── LC88 JS.md ├── articles ├── airticleAssests │ ├── 刷题进程.png │ ├── 多刷模板题.png │ ├── 日程截图.jpg │ ├── 狗头在办公室.jpg │ └── 聊天截图.png ├── 刷题心得.md ├── 技术面试的非技术.md └── 沟通居然也是程序员的要求.md ├── assets ├── DFSBinaryTreeSerializeAndDeserialize.jpg ├── LC142Floyd'sCircleFinding.jpg ├── LC1439多路归并压缩.jpg ├── LC327count部分.jpg ├── LCCN.png ├── deskset.jpg ├── download.svg ├── link.svg └── 排列公式.png ├── lcDaily ├── BinarySearchJS.md ├── LC1006.md ├── LC118.md ├── LC119.md ├── LC1190. Reverse Substrings Between Each Pair of Parentheses.md ├── LC1239. Maximum Length of a Concatenated String with Unique Characters.md ├── LC1269. Number of Ways to Stay in the Same Place After Some Steps.md ├── LC13. Roman to Integer.md ├── LC137.md ├── LC1442. Count Triplets That Can Form Two Arrays of Equal XOR.md ├── LC1482. Minimum Number of Days to Make m Bouquets.md ├── LC1486. XOR Operation in an Array.md ├── LC150.md ├── LC153.md ├── LC160. Intersection of Two Linked Lists.md ├── LC1603.md ├── LC1711. Count Good Meals.md ├── LC1723. Find Minimum Time to Finish All Jobs.md ├── LC1736. Latest Time by Replacing Hidden Digits.md ├── LC1846. Maximum Element After Decreasing and Rearranging.md ├── LC1928. Minimum Cost to Reach Destination in Time.md ├── LC263.md ├── LC27.md ├── LC28.md ├── LC344.md ├── LC374. Guess Number Higher or Lower.md ├── LC451. Sort Characters By Frequency.md ├── LC474. Ones and Zeroes.md ├── LC494. Target Sum.md ├── LC523. Continuous Subarray Sum.md ├── LC554. Brick Wall.md ├── LC5747. Splitting a String Into Descending Consecutive Values.md ├── LC5778. Minimum Number of Flips to Make the Binary String Alternating.md ├── LC5779. Minimum Space Wasted From Packaging.md ├── LC581. Shortest Unsorted Continuous Subarray.md ├── LC611. Valid Triangle Number.md ├── LC616. Add Bold Tag in String.md ├── LC645. Set Mismatch.md ├── LC653.md ├── LC664. Strange Printer.md ├── LC690. Employee Importance.md ├── LC692. Top K Frequent Words.md ├── LC740. Delete and Earn.md ├── LC783.md ├── LC852. Peak Index in a Mountain Array.md ├── LC872. Leaf-Similar Trees.md ├── LC897.md ├── LC909. Snakes and Ladders.md ├── LC91.md ├── LC938.md ├── LC981. Time Based Key-Value Store.md ├── LC993. Cousins in Binary Tree.md └── LCP 07. 传递信息.md ├── leetcodepp3 ├── BinarySearch │ ├── D29 LC69.md │ ├── D30 LC278.md │ ├── D31 Triple Inversion.md │ └── TDD32 Minimum-Light-Radius .md ├── BinaryTree │ ├── D13 LC104.md │ ├── D14 LC100.md │ ├── D15 LC129.md │ ├── D16 LC513.md │ ├── D17 LC297.md │ ├── D18 LC987.md │ ├── LC154.md │ ├── LC33.md │ └── LC81.md ├── DisjointSets │ ├── LC399. Evaluate Division.md │ └── LC990. 等式方程的可满足性.md ├── DynamicProgramming │ ├── LC1143最长公共子序列.md │ ├── LC139.md │ ├── LC198打家劫舍.md │ ├── LC300.md │ ├── LC322.md │ ├── LC368.md │ ├── LC377.md │ ├── LC416.md │ ├── LC494.md │ ├── LC518.md │ ├── LC53.md │ ├── LC62.md │ ├── LC673Number of Longest Increasing Subsequence.md │ ├── LC746.md │ └── MinSubSeq.md ├── Greedy │ ├── LC435.md │ ├── LC455.md │ ├── LC765.md │ └── LC881.md ├── Heap │ ├── LC1046. Last Stone Weight.md │ ├── LC1054. Distant Barcodes.md │ ├── LC215. Kth Largest Element in an Array.md │ ├── LC264. Ugly Number II.md │ ├── LC313. Super Ugly Number.md │ ├── LC347. Top K Frequent Elements.md │ ├── LC378. Kth Smallest Element in a Sorted Matrix.md │ ├── LC451. Sort Characters By Frequency.md │ ├── LC973. K Closest Points to Origin.md │ ├── Quicksort.md │ └── 面试题 17.14. Smallest K LCCI.md ├── LinkedList │ ├── D10 LC160.md │ ├── D11 LC142.md │ ├── D12 LC146.md │ ├── D7 LC61.md │ ├── D8 LC24.md │ └── D9 LC109.md ├── README.md ├── Search&BackTrack │ ├── LC113.md │ ├── LC1162.md │ ├── LC39.md │ ├── LC40.md │ ├── LC401.md │ ├── LC46.md │ ├── LC47.md │ ├── LC695.md │ ├── LC78.md │ └── LC90.md ├── SlidingWindow │ ├── D35 LC1456.md │ ├── D37 LC438.md │ ├── D38 LC76.md │ ├── D39 LC1423.md │ ├── LC1838.md │ └── LC1839.md ├── StringMatchingAlgorithms │ └── LC28. Implement strStr().md ├── Trie │ ├── LC208. Implement Trie (Prefix Tree).md │ ├── LC211. Design Add and Search Words Data Structure.md │ ├── LC648. Replace Words.md │ ├── LC677. Map Sum Pairs.md │ └── 面试题 17.17. Multi Search LCCI.md ├── TwoPointers │ ├── D25 LC867.md │ ├── D26 LC26.md │ ├── D27 LC35.md │ └── D28 LC239.md ├── foundation │ ├── D1 LC989.md │ ├── D2 LC821.md │ ├── D3 LC1381.md │ ├── D4 LC394.md │ ├── D5 LC232.md │ └── D6 LC768.md ├── hashtable │ ├── D19 LC1.md │ ├── D20 LC347.md │ ├── D21 LC447.md │ ├── D22 LC3.md │ ├── D23 LC30.md │ ├── D24 LC1590.md │ └── D24 LC560.md ├── 剪枝 │ ├── LC39.md │ ├── LC40. Combination Sum II.md │ ├── LC47. Permutations II.md │ └── LC814. Binary Tree Pruning.md └── 高频题 │ ├── D84 二叉树遍历.md │ ├── D85 反转链表.md │ ├── D86 位运算.md │ ├── D88 栈-有效括号.md │ ├── D90 前缀和.md │ └── D91 排序.md ├── leetcodepp4 ├── D1 LC989. Add to Array-Form of Integer.md ├── D10 LC 160. Intersection of Two Linked Lists.md ├── D11 LC142. Linked List Cycle II.md ├── D12 LC146. LRU Cache.md ├── D13 LC104. Maximum Depth of Binary Tree.md ├── D14 LC100. Same Tree.md ├── D15 LC129. Sum Root to Leaf Numbers.md ├── D16 LC513. Find Bottom Left Tree Value.md ├── D17 LC297. Serialize and Deserialize Binary Tree.md ├── D18 LC987. Vertical Order Traversal of a Binary Tree.md ├── D19 LC1.Two Sum.md ├── D2 LC821. Shortest Distance to a Character.md ├── D20 LC347. Top K Frequent Elements.md ├── D21 LC447. Number of Boomerangs.md ├── D22 LC3. Longest Substring Without Repeating Characters.md ├── D23 LC30. Substring with Concatenation of All Words.md ├── D24 LC1590. Make Sum Divisible by P.md ├── D25 LC876. Middle of the Linked List.md ├── D26 LC26. Remove Duplicates from Sorted Array.md ├── D27 LC35. Search Insert Position.md ├── D28 LC239. Sliding Window Maximum.md ├── D29 LC69. Sqrt(x).md ├── D3 LC1381. Design a Stack With Increment Operation.md ├── D30 LC278. First Bad Version.md ├── D31 Triple Inversion.md ├── D32 Minimum Light Radius.md ├── D33 Kth Pair Distance.md ├── D34 LC778. Swim in Rising Water.md ├── D35 LC1456. Maximum Number of Vowels in a Substring of Given Length.md ├── D36 LC837. New 21 Game.md ├── D37 LC438. Find All Anagrams in a String.md ├── D38 LC76. Minimum Window Substring.md ├── D39 Number of Operations to Decrement Target to Zero.md ├── D4 LC394. Decode String.md ├── D40 LC401. Binary Watch.md ├── D41 LC52. N-Queens II.md ├── D42 LC695. Max Area of Island.md ├── D43 LC1162. As Far from Land as Possible.md ├── D44 Shortest Cycle Containing Target Node.md ├── D45 Top View of a Tree.md ├── D46 LC746. Min Cost Climbing Stairs.md ├── D47 LC198. House Robber.md ├── D48 LC673. Number of Longest Increasing Subsequence.md ├── D49 LC1143. Longest Common Subsequence.md ├── D5 LC232. Implement Queue using Stacks.md ├── D50 LC62. Unique Paths.md ├── D51 LC688. Knight Probability in Chessboard.md ├── D54 LC494. Target Sum.md ├── D56 LC518. Coin Change 2.md ├── D57 LC455. Assign Cookies.md ├── D58 LC435. Non-overlapping Intervals.md ├── D59 LC881. Boats to Save People.md ├── D6 LC768. Max Chunks To Make Sorted II.md ├── D60 LC96. Unique Binary Search Trees.md ├── D61 LC23. Merge k Sorted Lists.md ├── D62 LC932. Beautiful Array.md ├── D63 LC260. Single Number III.md ├── D64 LC78. Subsets.md ├── D65 LC208. Implement Trie (Prefix Tree).md ├── D66 LC677. Map Sum Pairs.md ├── D67 面试题 17.17. 多次搜索.md ├── D68 LC924. Minimize Malware Spread.md ├── D69 LC1319. Number of Operations to Make Network Connected.md ├── D7 LC24. Swap Nodes in Pairs.md ├── D70 LC814. Binary Tree Pruning.md ├── D71 LC39. Combination Sum.md ├── D72 LC47. Permutations II.md ├── D77 LC215. Kth Largest Element in an Array.md ├── D78 LC1046. Last Stone Weight.md ├── D8 LC109. Convert Sorted List to Binary Search Tree.md ├── D80 LC451. Sort Characters By Frequency.md ├── D81 LC378. Kth Smallest Element in a Sorted Matrix.md ├── D82 LC1054. Distant Barcodes.md ├── D83 LC1206. Design Skiplist.md ├── D84 binaryTreeTraversal.md ├── D85 reverseLinkedList.md ├── D86 Bitwise Operation.md ├── D9 LC160. Intersection of Two Linked Lists.md └── README.md ├── leetcodepp5 ├── D1 LC821. Shortest Distance to a Character.md ├── D10 LC160. Intersection of Two Linked Lists.md ├── D16 LC513. Find Bottom Left Tree Value.md └── D17 LC297. Serialize and Deserialize Binary Tree.md ├── review └── D8 LC109. Convert Sorted List to Binary Search Tree.md └── 重点基础题 ├── LC108. Convert Sorted Array to Binary Search Tree.md ├── LC141. Linked List Cycle.md ├── LC206. Reverse Linked List.md ├── LC70. Climbing Stairs.md ├── LC94. Binary Tree Inorder Traversal.md └── TODOLC208. Implement Trie (Prefix Tree).md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | assets/debug.log 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.acceptSuggestionOnEnter": "off" 3 | } -------------------------------------------------------------------------------- /Basic200/BinarySearch/LC528. Random Pick with Weight.md: -------------------------------------------------------------------------------- 1 | ## LC 528. Random Pick with Weight 2 | 3 | - [二分法](#思路-二分法) 4 | 5 | ### 思路 二分法 6 | 7 | 这题好难 8 | review 9 | 重要的是加权平均的概率等于 10 | 有一个前缀和数组然后寻找最左插入位置 11 | 也就是寻找第一个大于等于 target 的值 12 | 13 | #### 代码 JavaScript 14 | 15 | ```JavaScript 16 | var Solution = function(w) { 17 | this.preSum = []; 18 | 19 | for(let i = 0; i < w.length; i++){ 20 | this.preSum[i] = (this.preSum[i - 1] || 0) + w[i] 21 | } 22 | this.sum = this.preSum[w.length - 1] 23 | }; 24 | 25 | /** 26 | * @return {number} 27 | */ 28 | Solution.prototype.pickIndex = function() { 29 | const target = Math.random() * this.sum; 30 | 31 | let left = 0, right = this.preSum.length - 1; 32 | 33 | while(left < right){ 34 | const mid = left + ((right - left) >> 1) 35 | 36 | if(this.preSum[mid] <= target) left = mid + 1 37 | else right = mid 38 | } 39 | 40 | return left; 41 | }; 42 | 43 | ``` 44 | 45 | #### 复杂度分析 46 | 47 | 时间复杂度:O(logN)
48 | 空间复杂度:O(1) 49 | -------------------------------------------------------------------------------- /Basic200/BinarySearch/LC69. Sqrt(x).md: -------------------------------------------------------------------------------- 1 | ## LC 69. Sqrt(x) 2 | 3 | - [二分法](#思路-二分法) 4 | 5 | ### 思路 二分法 6 | 7 | 注意这相当于寻找最右边的值 8 | 最后可以返回 right 9 | 因为比如[1,2,2,3,4] target = 2 10 | 在最后的时候 l = 3, r = 4 然后因为 mid = nums[3] => 3 11 | 3 > target right 最后会在正确的位置 12 | 13 | #### 代码 JavaScript 14 | 15 | ```JavaScript 16 | var mySqrt = function(x) { 17 | let left = 0, right = x 18 | 19 | while(left <= right){ 20 | let mid = left + ((right - left) >> 1) 21 | 22 | if(mid * mid <= x){ 23 | left = mid + 1 24 | }else{ 25 | right = mid - 1 26 | } 27 | 28 | } 29 | return right; 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 36 | 时间复杂度:
37 | 空间复杂度: 38 | -------------------------------------------------------------------------------- /Basic200/BinaryTree/LC105. Construct Binary Tree from Preorder and Inorder Traversal.md: -------------------------------------------------------------------------------- 1 | ## LC105. Construct Binary Tree from Preorder and Inorder Traversal 2 | 3 | https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ 4 | 5 | - [5/24/2021 二刷](#思路-5/24/2021二刷) 6 | 7 | ### 思路 5/24/2021 二刷 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var buildTree = function(preorder, inorder) { 13 | if(!preorder.length) return null; 14 | const root = new TreeNode(preorder[0]) 15 | const rootIndex = inorder.indexOf(preorder[0]) 16 | //preorder[0] 一定是root 17 | //因为inoder是左| 根| 右 所以 [0..根] 的index 就是左边节点的个数 18 | //因为是同一棵树所以节点个数是一样的,所以有1, rootIndex+1 19 | root.left = buildTree(preorder.slice(1, rootIndex+1 ), inorder.slice(0, rootIndex)) 20 | root.right = buildTree(preorder.slice(rootIndex + 1), inorder.slice(rootIndex + 1)) 21 | 22 | return root; 23 | }; 24 | 25 | ``` 26 | 27 | #### 复杂度分析 28 | 29 | 时间复杂度:O(N)
30 | 空间复杂度:O(N) 31 | -------------------------------------------------------------------------------- /Basic200/DP/LC62. Unique Paths.md: -------------------------------------------------------------------------------- 1 | ## LC 62. Unique Paths 2 | 3 | - [动态规划 dp](#思路-动态规划dp) 4 | 5 | ### 思路 动态规划 dp 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var uniquePaths = function(m, n) { 11 | const dp = Array.from({length: m}).map(() => Array.from({length:n}).fill(0)) 12 | 13 | dp[0][0] = 1 14 | for(let i = 0; i < m; i++){ 15 | dp[i][0] = 1 16 | } 17 | for(let j = 0; j < n; j++){ 18 | dp[0][j] = 1 19 | } 20 | 21 | for(let i = 1; i < m; i++){ 22 | for(let j = 1; j < n; j++){ 23 | dp[i][j] = dp[i - 1][j] + dp[i][j -1] 24 | } 25 | } 26 | 27 | return dp[m -1 ][n-1] 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 34 | 时间复杂度:O(MN)
35 | 空间复杂度:O(MN) 36 | -------------------------------------------------------------------------------- /Basic200/Heap/Template.md: -------------------------------------------------------------------------------- 1 | ## LC 2 | 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | 12 | ``` 13 | 14 | #### 复杂度分析 15 | 16 | 时间复杂度:
17 | 空间复杂度: 18 | -------------------------------------------------------------------------------- /Basic200/LC102. Binary Tree Level Order Traversal.md: -------------------------------------------------------------------------------- 1 | ## LC 102. Binary Tree Level Order Traversal 2 | 3 | https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ 4 | 5 | ### 思路 6 | 7 | BFS 8 | 注意要记录每层的长度 9 | 10 | ### 代码 11 | 12 | ```JavaScript 13 | var levelOrder = function(root) { 14 | const res = []; 15 | if(!root) return res; 16 | let queue = [root] 17 | 18 | while(queue.length > 0){ 19 | let levelSize = queue.length; 20 | let temp = []; 21 | for(let i = 0; i < levelSize; i++){ 22 | let cur = queue.shift(); 23 | temp.push(cur.val); 24 | cur.left && queue.push(cur.left); 25 | cur.right && queue.push(cur.right); 26 | } 27 | // console.log(temp) 28 | res.push(temp) 29 | } 30 | 31 | return res; 32 | }; 33 | 34 | ``` 35 | 36 | ### 复杂度分析 37 | 38 | 时间复杂度:O(N) 39 | 空间复杂度:O(N) 40 | -------------------------------------------------------------------------------- /Basic200/LC103. Binary Tree Zigzag Level Order Traversal.md: -------------------------------------------------------------------------------- 1 | ## LC 103. Binary Tree Zigzag Level Order Traversal 2 | 3 | ### 思路 4 | 5 | BFS 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var zigzagLevelOrder = function(root) { 11 | if(root == null) return []; 12 | let queue = [root] 13 | let flip = false; 14 | const result = []; 15 | while(queue.length > 0){ 16 | let levelSize = queue.length; 17 | let currentLevel = []; 18 | for(let i = 0; i < levelSize; i++){ 19 | let cur = queue.shift(); 20 | currentLevel.push(cur.val); 21 | cur.left && queue.push(cur.left) 22 | cur.right && queue.push(cur.right) 23 | } 24 | currentLevel = flip ? currentLevel.reverse() : currentLevel 25 | result.push(currentLevel); 26 | flip = !flip; 27 | } 28 | 29 | return result; 30 | }; 31 | 32 | ``` 33 | 34 | ### 复杂度分析 35 | 36 | 时间复杂度:O(N) 37 | 空间复杂度:O(N) 38 | -------------------------------------------------------------------------------- /Basic200/LC107. Binary Tree Level Order Traversal II.md: -------------------------------------------------------------------------------- 1 | ## LC 107. Binary Tree Level Order Traversal II 2 | 3 | - [BFS 带层模板题](#思路-BFS带层模板题) 4 | 5 | ### 思路 BFS 带层模板题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var levelOrderBottom = function(root) { 11 | if(!root) return [] 12 | const res = []; 13 | const queue = [root] 14 | 15 | while(queue.length){ 16 | const levelSize = queue.length 17 | const levelTemp = [] 18 | 19 | for(let i = 0; i < levelSize; i++){ 20 | const node = queue.shift() 21 | levelTemp.push(node.val) 22 | 23 | node.left && queue.push(node.left) 24 | node.right && queue.push(node.right) 25 | } 26 | res.unshift(levelTemp) 27 | } 28 | 29 | return res; 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 36 | 时间复杂度:O(N)
37 | 空间复杂度:O(N) 38 | -------------------------------------------------------------------------------- /Basic200/LC113. Path Sum II.md: -------------------------------------------------------------------------------- 1 | ## LC 113. Path Sum II 2 | 3 | https://leetcode-cn.com/problems/path-sum-ii/ 4 | 5 | - [回溯](#思路-回溯) 6 | 7 | ### 思路 回溯 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var pathSum = function(root, targetSum) { 13 | const result = []; 14 | if(!root) return result; 15 | 16 | var backTrack = function(root, tempList, remaining){ 17 | if(remaining == 0 && (!root.left && !root.right)){ 18 | result.push([...tempList]) 19 | return; 20 | } 21 | 22 | root.left && backTrack(root.left, tempList.concat([root.left.val]), remaining - root.left.val) 23 | root.right && backTrack(root.right, tempList.concat([root.right.val]), remaining - root.right.val) 24 | } 25 | 26 | backTrack(root, [root.val], targetSum- root.val) 27 | return result; 28 | 29 | }; 30 | 31 | ``` 32 | 33 | #### 复杂度分析 34 | 35 | 时间复杂度:O(N^2) 此时,路径的数目为 O(N),并且每一条路径的节点个数也为 O(N),因此要将这些路径全部添加进答案中,时间复杂度为 O(N^2) 36 | 37 | 空间复杂度: O(N),其中 NN 是树的节点数。空间复杂度主要取决于栈空间的开销, 38 | -------------------------------------------------------------------------------- /Basic200/LC13. Roman to Integer.md: -------------------------------------------------------------------------------- 1 | ## LC 13. Roman to Integer 2 | 3 | ### 思路 4 | 5 | Notice that for Roman numbers, if the smaller one appears first, it means -- 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var romanToInt = function(s) { 11 | let ans = 0 12 | 13 | const dict = new Map(); 14 | dict.set('I', 1); 15 | dict.set('V', 5); 16 | dict.set('X', 10); 17 | dict.set('L', 50); 18 | dict.set('C', 100); 19 | dict.set('C', 100); 20 | dict.set('D', 500); 21 | dict.set('M', 1000); 22 | 23 | for(let i = 0; i < s.length; i++){ 24 | if(i != s.length - 1 && dict.get(s[i]) < dict.get(s[i + 1])){ 25 | ans -= dict.get(s[i]) 26 | }else{ 27 | ans += dict.get(s[i]) 28 | } 29 | } 30 | 31 | return ans; 32 | }; 33 | 34 | ``` 35 | 36 | #### 复杂度分析 37 | 38 | 时间复杂度: O(N)
39 | 空间复杂度:O(1) 40 | -------------------------------------------------------------------------------- /Basic200/LC13.md: -------------------------------------------------------------------------------- 1 | ## LC 13 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```JavaScript 8 | var romanToInt = function(s) { 9 | let keys = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; 10 | let values = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; 11 | 12 | let ans = 0; 13 | while(s.length > 0){ 14 | for(let i = 0; i < values.length; i++){ 15 | if(s[0] == values[i] || s[0]+s[1] == values[i]){ 16 | ans+= keys[i] 17 | s = s.slice(values[i].length ) 18 | break; 19 | } 20 | } 21 | } 22 | return ans; 23 | }; 24 | 25 | ``` 26 | 27 | ### 复杂度分析 28 | 29 | 时间复杂度:O(N) 30 | 空间复杂度:O(1) 31 | -------------------------------------------------------------------------------- /Basic200/LC136. Single Number.md: -------------------------------------------------------------------------------- 1 | ## LC 136. Single Number 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```JavaScript 8 | var singleNumber = function(nums) { 9 | nums = nums.sort((a,b) => a-b) 10 | 11 | for(let i = 0; i < nums.length; i = i + 2){ 12 | if(nums[i] != nums[i+1]) return nums[i] 13 | } 14 | }; 15 | 16 | ``` 17 | 18 | ### 复杂度分析 19 | 20 | 时间复杂度: 21 | 空间复杂度: 22 | -------------------------------------------------------------------------------- /Basic200/LC138. Copy List with Random Pointer.md: -------------------------------------------------------------------------------- 1 | ## LC 138. Copy List with Random Pointer 2 | 3 | - [迭代](#思路-迭代) 4 | - [递归](#思路-递归) todo 5 | 6 | ### 思路 迭代 7 | 8 | ### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var copyRandomList = function(head) { 12 | if(!head) return head; 13 | 14 | let cur = head; 15 | const memo = new Map(); 16 | 17 | while(cur){ 18 | memo.set(cur, new Node(cur.val)) 19 | cur = cur.next 20 | } 21 | cur = head 22 | while(cur){ 23 | memo.get(cur).next = memo.get(cur.next) || null 24 | memo.get(cur).random = memo.get(cur.random) || null 25 | cur = cur.next 26 | } 27 | 28 | return memo.get(head) 29 | }; 30 | 31 | ``` 32 | 33 | ### 复杂度分析 34 | 35 | 时间复杂度:O(N)
36 | 空间复杂度:O(N) 37 | -------------------------------------------------------------------------------- /Basic200/LC14.md: -------------------------------------------------------------------------------- 1 | ## LC 14 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```JavaScript 8 | var longestCommonPrefix = function(strs) { 9 | if(strs.length == 1) return strs[0] 10 | let ans = '' 11 | for(let i = 0; i < strs[0].length; i++){ 12 | let temp; 13 | for(let j = 0; j < strs.length; j++){ 14 | if(j == 0){ 15 | temp = strs[j][i] 16 | }else if(j == strs.length - 1 && strs[j][i] == temp){ 17 | ans += strs[j][i]; 18 | }else if(strs[j][i] != temp){ 19 | return ans 20 | } 21 | } 22 | } 23 | 24 | return ans; 25 | }; 26 | 27 | ``` 28 | 29 | ### 复杂度分析 30 | 31 | 时间复杂度:O(N \* shortest element length) 32 | 空间复杂度:O(1) 33 | -------------------------------------------------------------------------------- /Basic200/LC141. Linked List Cycle.md: -------------------------------------------------------------------------------- 1 | ## LC 141. Linked List Cycle 2 | 3 | ### 思路 4 | 5 | 快慢指针 6 | 或者用 set 来判断也可以,用 set 就是遍历看是否有 set.has 7 | 8 | ### 代码 9 | 10 | ```JavaScript 11 | var hasCycle = function(head) { 12 | if(!head || !head.next || !head.next.next) return false; //注意特别的corner case 13 | let slow = head, fast = head.next.next; 14 | 15 | while(slow != fast){ 16 | if(!fast || !slow) return false; 17 | slow = slow.next; 18 | fast = fast.next ? fast.next.next : null //注意要判断fast.next 在这或者在18 19 | } 20 | // console.log(slow, fast) 21 | return slow == fast; 22 | }; 23 | 24 | ``` 25 | 26 | ### 复杂度分析 27 | 28 | 时间复杂度:O(N) 29 | 空间复杂度:O(1) 30 | -------------------------------------------------------------------------------- /Basic200/LC169. Majority Element.md: -------------------------------------------------------------------------------- 1 | ## LC169. Majority Element 2 | 3 | ### 思路 4 | 5 | hash 6 | 7 | ### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var majorityElement = function(nums) { 11 | let memo = new Map(); 12 | let target = nums.length 13 | target = target % 2 == 0 ? target / 2 : Math.ceil(target/2) 14 | 15 | for(let i = 0; i < nums.length; i++){ 16 | let cur = nums[i] 17 | memo.set(cur, (memo.get(cur) || 0) + 1) 18 | if(memo.get(cur) == target) return cur 19 | } 20 | }; 21 | 22 | ``` 23 | 24 | ### 复杂度分析 25 | 26 | 时间复杂度:O(N) 27 | 空间复杂度:O(N) 28 | 29 | ### 思路 30 | 31 | 众数在数组被排序后一定会在中间 32 | 33 | ### 代码 JavaScript 34 | 35 | ```JavaScript 36 | var majorityElement = function(nums) { 37 | nums = nums.sort((a, b) => a - b) 38 | let target = nums.length >> 1 39 | 40 | return nums[target] 41 | }; 42 | 43 | ``` 44 | 45 | ### 复杂度分析 46 | 47 | 时间复杂度:O(NlogN) N 遍历 logN 是排序 48 | 空间复杂度:O(logN) 49 | -------------------------------------------------------------------------------- /Basic200/LC17. Letter Combinations of a Phone Number.md: -------------------------------------------------------------------------------- 1 | ## LC 17. Letter Combinations of a Phone Number 2 | 3 | https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/ 4 | 5 | ### 思路 6 | 7 | backtrack 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | var letterCombinations = function(digits) { 13 | if(digits.length == 0) return []; 14 | let result = []; 15 | const memo = new Map([['2','abc'], ['3','def'],['4','ghi'], ['5', "jkl"], ['6', "mno"], ['7', "pqrs"], ['8', "tuv"], ['9', "wxyz"] ]) 16 | 17 | var backTrack = function(curStr, i){ 18 | if(i > digits.length - 1) { 19 | result.push(curStr); 20 | return ; 21 | } 22 | 23 | let letters = memo.get(digits[i]); 24 | letters = letters.split(''); 25 | for(const letter of letters){ //一个字母是一个选择 26 | backTrack(curStr+letter, i + 1); 27 | } 28 | } 29 | 30 | backTrack('',0) 31 | return result; 32 | }; 33 | 34 | ``` 35 | 36 | ### 复杂度分析 37 | 38 | 时间复杂度:O(3^m \* 4^n) 39 | 空间复杂度:O(3m+4n) => O(m +n) 40 | -------------------------------------------------------------------------------- /Basic200/LC199. Binary Tree Right Side View.md: -------------------------------------------------------------------------------- 1 | ## LC 199. Binary Tree Right Side View 2 | 3 | - [BFS](#思路-BFS) 4 | 5 | ### 思路 BFS 6 | 7 | 经典 BFS 带层 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var rightSideView = function(root) { 13 | if(!root) return [] 14 | const res =[] 15 | const queue = [root] 16 | while(queue.length){ 17 | const levelSize = queue.length 18 | for(let i = 0; i < levelSize; i++){ 19 | const node = queue.shift() 20 | if(i == levelSize - 1) res.push(node.val) 21 | node.left && queue.push(node.left) 22 | node.right && queue.push(node.right) 23 | } 24 | } 25 | 26 | return res; 27 | }; 28 | 29 | ``` 30 | 31 | #### 复杂度分析 32 | 33 | 时间复杂度:O(N)
34 | 空间复杂度:O(N) 栈的开销 35 | -------------------------------------------------------------------------------- /Basic200/LC206. Reverse Linked List.md: -------------------------------------------------------------------------------- 1 | ## LC 206 2 | 3 | https://leetcode-cn.com/problems/reverse-linked-list/ 4 | 5 | ### 思路 6 | 7 | 迭代 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | var reverseList = function(head) { 13 | let pre = null, cur = head; 14 | 15 | while(cur){ 16 | let next = cur.next; 17 | cur.next = pre; 18 | pre = cur; 19 | cur = next; 20 | } 21 | 22 | return pre; 23 | }; 24 | 25 | ``` 26 | 27 | ### 复杂度分析 28 | 29 | 时间复杂度:O(N) 30 | 空间复杂度:O(1) 31 | 32 | ### 思路 33 | 34 | 递归 35 | 36 | ### 代码 37 | 38 | ```JavaScript 39 | var reverseList = function(head) { 40 | if(!head || !head.next) return head; 41 | 42 | let newHead = reverseList(head.next); 43 | head.next.next = head; 44 | head.next = null; 45 | 46 | return newHead; 47 | }; 48 | 49 | ``` 50 | 51 | ### 复杂度分析 52 | 53 | 时间复杂度:O(N) 54 | 空间复杂度:O(N) 55 | -------------------------------------------------------------------------------- /Basic200/LC22.md: -------------------------------------------------------------------------------- 1 | ## LC 22 2 | 3 | ### 思路 4 | 5 | https://leetcode-cn.com/problems/generate-parentheses/ 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | /** 11 | * @param {number} n 12 | * @return {string[]} 13 | */ 14 | var generateParenthesis = function(n) { 15 | let ans = []; 16 | 17 | var backTrack = function(curStr, left, right){ 18 | ///结束条件 19 | if(curStr.length == 2 * n){ 20 | ans.push(curStr.join('')); 21 | return; 22 | } 23 | 24 | //每个选择中 25 | if(left < n){ 26 | curStr.push('(') 27 | backTrack(curStr, left + 1, right) //下一个选择 28 | curStr.pop(); 29 | } 30 | if(right < left){ 31 | curStr.push(')') 32 | backTrack(curStr, left, right + 1) //下一个选择 33 | curStr.pop(); 34 | } 35 | } 36 | 37 | backTrack([],0,0) 38 | return ans; 39 | }; 40 | 41 | ``` 42 | 43 | ### 复杂度分析 44 | 45 | 时间复杂度: 46 | 空间复杂度: 47 | -------------------------------------------------------------------------------- /Basic200/LC237. Delete Node in a Linked List.md: -------------------------------------------------------------------------------- 1 | ## LC 237. Delete Node in a Linked List 2 | 3 | https://leetcode-cn.com/problems/delete-node-in-a-linked-list/ -- 4 | Write a function to delete a node in a singly-linked list. You will not be given access to the head of the list, instead you will be given access to the node to be deleted directly. 5 | 6 | It is guaranteed that the node to be deleted is not a tail node in the list. 7 | 8 | ### 思路 9 | 10 | 让现在的 node 的值变成下一个节点的值 11 | 然后删除下一个节点 12 | 13 | ### 代码 JavaScript 14 | 15 | ```JavaScript 16 | var deleteNode = function(node) { 17 | node.val = node.next.val 18 | let next = node.next.next 19 | node.next = next; 20 | }; 21 | 22 | ``` 23 | 24 | ### 复杂度分析 25 | 26 | 时间复杂度:O(1)
27 | 空间复杂度:O(1) 28 | -------------------------------------------------------------------------------- /Basic200/LC240. Search a 2D Matrix II.md: -------------------------------------------------------------------------------- 1 | ## LC 240. Search a 2D Matrix II 2 | 3 | https://leetcode-cn.com/problems/search-a-2d-matrix-ii/ 4 | 5 | - [mn](#思路-mn) 6 | 7 | ### 思路 mn 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | /** 13 | * @param {number[][]} matrix 14 | * @param {number} target 15 | * @return {boolean} 16 | */ 17 | var searchMatrix = function(matrix, target) { 18 | let row = matrix.length - 1, col = 0; 19 | 20 | while(row >= 0 && col >= 0 && col < matrix[0].length){ 21 | if(matrix[row][col] > target){ 22 | row-- 23 | }else if(matrix[row][col] < target){ 24 | col++ 25 | } 26 | else if( matrix[row][col] == target ){ 27 | return true 28 | } 29 | } 30 | 31 | return false; 32 | }; 33 | 34 | ``` 35 | 36 | #### 复杂度分析 37 | 38 | 时间复杂度:O(M+N)
39 | 空间复杂度:O(1) 40 | -------------------------------------------------------------------------------- /Basic200/LC45. Jump Game II.md: -------------------------------------------------------------------------------- 1 | ## LC 45. Jump Game II 2 | 3 | - [贪心](#思路-贪心) 4 | 5 | ### 思路 贪心 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var jump = function(nums) { 11 | 12 | let step = 0 13 | let reachable = 0 14 | let end = 0 15 | for(let i = 0; i < nums.length - 1; i++){ 16 | reachable = Math.max(reachable, i + nums[i]) 17 | //只有当reach到当前end的时候才需要迈出新的一步 18 | if(i == end){ 19 | end = reachable 20 | step++ 21 | } 22 | } 23 | 24 | return step; 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 31 | 时间复杂度:O(N)
32 | 空间复杂度:O(1) 33 | -------------------------------------------------------------------------------- /Basic200/LC49.md: -------------------------------------------------------------------------------- 1 | ## LC 49. Group Anagrams 2 | 3 | ### 思路 4 | 5 | 排序获得相同 key 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var groupAnagrams = function(strs) { 11 | let memo = new Map(); 12 | 13 | for(let word of strs){ 14 | let temp = Array.from(word).sort(); //排序获得相同key 15 | temp = temp.join(''); 16 | memo.set(temp, (memo.get(temp) || []).concat([word])) 17 | } 18 | 19 | return [...memo.values()] 20 | }; 21 | 22 | ``` 23 | 24 | ### 复杂度分析 25 | 26 | 时间复杂度:O(N) 27 | 空间复杂度:O(N) 28 | -------------------------------------------------------------------------------- /Basic200/LC54. Spiral Matrix.md: -------------------------------------------------------------------------------- 1 | ## LC 54. Spiral Matrix 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```JavaScript 8 | var spiralOrder = function(matrix) { 9 | let top = 0, bottom = matrix.length - 1, left = 0, right = matrix[0].length - 1; 10 | const res = []; 11 | while(bottom > top && right > left){ 12 | for(let i = left; i < right; i++) res.push(matrix[top][i]); 13 | for(let i = top; i < bottom; i++) res.push(matrix[i][right]); 14 | for(let i = right; i > left; i--) res.push(matrix[bottom][i]) 15 | for(let i = bottom; i >top; i--) res.push(matrix[i][left]) 16 | right--; 17 | left++; 18 | top++; 19 | bottom--; 20 | } 21 | 22 | if(top == bottom){ 23 | for(let i = left; i<= right; i++) res.push(matrix[top][i]) 24 | }else if(left == right){ 25 | for(let i = top; i<= bottom; i++) res.push(matrix[i][left]) 26 | } 27 | 28 | return res; 29 | }; 30 | 31 | ``` 32 | 33 | ### 复杂度分析 34 | 35 | 时间复杂度:O(MN) 36 | 空间复杂度:O(1) 37 | -------------------------------------------------------------------------------- /Basic200/LC55. Jump Game.md: -------------------------------------------------------------------------------- 1 | ## LC 55. Jump Game 2 | 3 | - [贪心](#思路-贪心) 4 | 5 | ### 思路 贪心 6 | 7 | 5/28/2021 二刷 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var canJump = function(nums) { 13 | let reachable = 0 14 | 15 | for(let i = 0; i < nums.length; i++){ 16 | if(reachable < i) return false; 17 | reachable = Math.max(reachable, nums[i] + i) 18 | } 19 | return reachable >= nums.length - 1 20 | }; 21 | 22 | ``` 23 | 24 | #### 复杂度分析 25 | 26 | 时间复杂度:O(N)
27 | 空间复杂度:O(1) 28 | 29 | ### 思路 30 | 31 | 维护一个可以达到的最远距离 32 | 注意 while 之后出来的 i 是恰好不满足的条件的 33 | 34 | ### 代码 35 | 36 | ```JavaScript 37 | var canJump = function(nums) { 38 | let i = 0 39 | let furthest = nums[i]; 40 | while(i <= furthest){ 41 | furthest = Math.max(furthest, nums[i] + i) 42 | i++; 43 | } 44 | // console.log(i) 45 | return i - 1 >= nums.length - 1 46 | }; 47 | 48 | ``` 49 | 50 | ### 复杂度分析 51 | 52 | 时间复杂度:O(N) 53 | 空间复杂度:O(1) 54 | -------------------------------------------------------------------------------- /Basic200/LC56. Merge Intervals.md: -------------------------------------------------------------------------------- 1 | ## LC 56. Merge Intervals 2 | 3 | https://leetcode-cn.com/problems/merge-intervals/ 4 | 5 | ### 思路 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var merge = function(intervals) { 11 | const result = []; 12 | intervals = intervals.sort((a,b) => a[0] - b[0]) 13 | 14 | for(let i = 0; i < intervals.length; i++){ 15 | let j = i; 16 | let min = intervals[j][0]; //现在区间里最小的数字 17 | let max = intervals[j][1]; //现在区间里最大的数字 18 | while(j < intervals.length - 1 && max >= intervals[j+1][0]){ //如果现在区间里最大的数字比下一个区间里开头的数字大 19 | //那么他们就能链接 20 | min = Math.min(min, intervals[j+1][0]) //更新最小的数字 21 | max = Math.max(max, intervals[j+1][1])//更新最大的数字 22 | j++; 23 | } 24 | result.push([min, max]) 25 | i = j //省去一些计算 26 | } 27 | return result; 28 | } 29 | 30 | ``` 31 | 32 | ### 复杂度分析 33 | 34 | 时间复杂度:O(NlogN) 扫描 \* 排序 35 | 空间复杂度:O(logn) 36 | -------------------------------------------------------------------------------- /Basic200/LC5773. Maximum Value after Insertion.md: -------------------------------------------------------------------------------- 1 | ## LC 5773. Maximum Value after Insertion 2 | 3 | 数的最大值和最小值 4 | 5 | - [解法副标题](#思路-解法副标题) 6 | 7 | ### 思路 解法副标题 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var maxValue = function(n, x) { 13 | //插入得到数字的最小值 14 | if(n[0] == '-'){ 15 | for(let i = 1; i < n.length; i++){ 16 | if(n[i] > x){ 17 | return n.slice(0,i) + x + n.slice(i) 18 | } 19 | } 20 | return n + x 21 | //插入得到数字的最大值 22 | }else{ 23 | for(let i = 0; i < n.length; i++){ 24 | if(n[i] < x){ 25 | return n.slice(0,i) + x + n.slice(i) 26 | } 27 | } 28 | return n + x 29 | } 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 36 | 时间复杂度:
37 | 空间复杂度: 38 | -------------------------------------------------------------------------------- /Basic200/LC58. Length of Last Word.md: -------------------------------------------------------------------------------- 1 | ## LC 58. Length of Last Word 2 | 3 | ### 思路 4 | 5 | ### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var lengthOfLastWord = function(s) { 9 | a = s.split(' ') 10 | for(let i = a.length - 1; i >= 0; i--){ 11 | if(a[i].length > 0){ 12 | return a[i].length 13 | } 14 | } 15 | return 0; 16 | }; 17 | 18 | ``` 19 | 20 | ### 复杂度分析 21 | 22 | 时间复杂度:O(NlogN) 23 | 空间复杂度:O(1) 24 | -------------------------------------------------------------------------------- /Basic200/LC60. Permutation Sequence.md: -------------------------------------------------------------------------------- 1 | ## LC 60. Permutation Sequence 2 | 3 | - [普通模拟](#思路-普通模拟) 4 | todo reviewON2 的做法 5 | 6 | ### 思路 普通模拟 7 | 8 | 注意 return 的地方! 9 | 10 | #### 代码 JavaScript 11 | 12 | ```JavaScript 13 | /** 14 | * @param {number} n 15 | * @param {number} k 16 | * @return {string} 17 | */ 18 | var getPermutation = function(n, k) { 19 | 20 | let count = 0 21 | var permutation = function(tempList){ 22 | if(tempList.size === n){ 23 | count++ 24 | if(count == k){ 25 | let colon = new Set(tempList) 26 | return [...colon].join('') 27 | } 28 | return; 29 | } 30 | 31 | for(let i = 1; i <= n; i++){ 32 | if(tempList.has(i)) continue 33 | tempList.add(i) 34 | const res = permutation(tempList) 35 | tempList.delete(i) 36 | if(res){ 37 | return res; 38 | } 39 | } 40 | } 41 | 42 | return permutation(new Set()) 43 | 44 | }; 45 | 46 | ``` 47 | 48 | #### 复杂度分析 49 | 50 | 时间复杂度:
51 | 空间复杂度: 52 | -------------------------------------------------------------------------------- /Basic200/LC66. Plus One.md: -------------------------------------------------------------------------------- 1 | ## LC 66. Plus One 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```JavaScript 8 | var plusOne = function(digits) { 9 | 10 | for(let i = digits.length - 1; i >= -1; i--){ 11 | if(i == -1) digits.unshift(1) //如果需要额外增加一个原来没有的digit,那么就是i == -1 的时候 12 | 13 | let temp = digits[i]; 14 | temp++; 15 | 16 | if(temp < 10){ //判断是否需要进位 17 | digits[i] = temp; //如果不需要的话,退出循环 18 | break; 19 | }else{ 20 | digits[i] = temp % 10; 21 | } 22 | } 23 | return digits; 24 | }; 25 | 26 | ``` 27 | 28 | ### 复杂度分析 29 | 30 | 时间复杂度:O(N) 31 | 空间复杂度:O(1) 32 | -------------------------------------------------------------------------------- /Basic200/LC7.md: -------------------------------------------------------------------------------- 1 | ## LC 7 2 | 3 | https://leetcode-cn.com/problems/reverse-integer/ 4 | 5 | ### 思路 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var reverse = function(x) { 11 | if(x < 10 && x > -10) return x; 12 | let negative = x < 0 ? true : false; 13 | x = Math.abs(x); 14 | let result = 0; 15 | while(x >= 10){ 16 | result = result * 10; 17 | result += x % 10; 18 | x = Math.floor(x/10) 19 | } 20 | result = result * 10 + x 21 | if(result > Math.pow(2,31)) return 0; 22 | 23 | return negative ? -result : result; 24 | }; 25 | 26 | ``` 27 | 28 | ### 复杂度分析 29 | 30 | 时间复杂度:O(log(x)) 31 | 空间复杂度:O(1) 32 | -------------------------------------------------------------------------------- /Basic200/LC875. Koko Eating Bananas.md: -------------------------------------------------------------------------------- 1 | ## LC 875. Koko Eating Bananas 2 | 3 | - [二分](#思路-二分) 4 | 5 | ### 思路 二分 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var minEatingSpeed = function(piles, h) { 11 | 12 | var totalTime = function(k){ 13 | //returns the h to eat all bananas 14 | let ans = 0; 15 | for(let pile of piles){ 16 | ans += Math.ceil(pile / k) 17 | } 18 | // console.log(k, ans) 19 | return ans 20 | } 21 | 22 | let left = 1, right = Math.max(...piles) 23 | 24 | 25 | while(left < right){ 26 | const speed = left + ((right - left) >> 1) 27 | 28 | let time = totalTime(speed) 29 | 30 | if(time > h){ 31 | left = speed + 1 32 | }else{ 33 | right = speed 34 | } 35 | } 36 | 37 | return left; 38 | 39 | }; 40 | 41 | ``` 42 | 43 | #### 复杂度分析 44 | 45 | 时间复杂度:O(N logW) W 是最大香蕉堆的数量
46 | 空间复杂度:O(1) 47 | -------------------------------------------------------------------------------- /Basic200/LC9.md: -------------------------------------------------------------------------------- 1 | ## LC 9 2 | 3 | ### 思路 4 | 5 | 双指针 转换为字符串 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var isPalindrome = function(x) { 11 | // if(x < 0) return false; 12 | x = x.toString(); 13 | let left= 0, right = x.length - 1; 14 | 15 | while(left < right){ 16 | if(x[left] != x[right]) return false; 17 | left++; 18 | right--; 19 | } 20 | return true; 21 | }; 22 | 23 | ``` 24 | 25 | ### 复杂度分析 26 | 27 | 时间复杂度:O(N) 28 | 空间复杂度:O(1) 29 | 30 | ### 思路 31 | 32 | 只转换一半,然后对比他们是否相等 33 | 34 | ### 代码 35 | 36 | ```JavaScript 37 | var isPalindrome = function(x) { 38 | if(x < 0 || (x % 10 == 0 && x != 0)) return false; 39 | let temp = 0; 40 | while(temp < x){ 41 | temp = temp * 10 + x % 10; 42 | x = Math.floor(x / 10); 43 | } 44 | // console.log(temp, x) 45 | return (temp == x) || (Math.floor(temp / 10) == x) ; //第二种情况是在x的原长度为奇数的情况下 46 | }; 47 | 48 | ``` 49 | 50 | ### 复杂度分析 51 | 52 | 时间复杂度:O(log(n)) 53 | 空间复杂度:O(1) 54 | -------------------------------------------------------------------------------- /Basic200/MonotonicStack/LC739. Daily Temperatures.md: -------------------------------------------------------------------------------- 1 | ## LC 739. Daily Temperatures 2 | 3 | https://leetcode-cn.com/problems/daily-temperatures/ 4 | 5 | ### 思路 单调栈- 递减 6 | 7 | Lucifer 写的真不错 8 | 找出第一个破坏规则的坏人(就是第一天变暖的时候 9 | 10 | #### 代码 JavaScript 11 | 12 | ```JavaScript 13 | var dailyTemperatures = function(temperatures) { 14 | const ans = new Array(temperatures.length).fill(0) 15 | //递减单调栈 16 | const stack = []; 17 | for(let i = 0; i < temperatures.length; i++){ 18 | while(stack.length > 0 && temperatures[stack[stack.length - 1]] < temperatures[i]){ 19 | let last = stack.pop() 20 | ans[last] = i - last 21 | } 22 | stack.push(i) 23 | } 24 | 25 | return ans; 26 | }; 27 | 28 | ``` 29 | 30 | #### 复杂度分析 31 | 32 | 时间复杂度:O(N)
33 | 空间复杂度:O(N) 34 | -------------------------------------------------------------------------------- /Basic200/T/LC20. Valid Parentheses.md: -------------------------------------------------------------------------------- 1 | ## LC 20. Valid Parentheses 2 | 3 | Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. 4 | 5 | An input string is valid if: 6 | 7 | Open brackets must be closed by the same type of brackets. 8 | Open brackets must be closed in the correct order. 9 | 10 | - [栈](#思路-栈) 11 | 12 | ### 思路 栈 13 | 14 | #### 代码 JavaScript 15 | 16 | ```JavaScript 17 | var isValid = function(s) { 18 | const stack = []; 19 | const memo = new Map(); 20 | memo.set('(', ')') 21 | memo.set('[', ']') 22 | memo.set('{', '}') 23 | 24 | for(const char of s){ 25 | if(memo.has(char)){ 26 | stack.push(memo.get(char)) 27 | }else{ 28 | let temp = stack.pop() 29 | if(temp !== char) return false; 30 | } 31 | } 32 | 33 | return stack.length === 0 34 | 35 | }; 36 | 37 | ``` 38 | 39 | #### 复杂度分析 40 | 41 | 时间复杂度:O(N)
42 | 空间复杂度:O(N) 43 | -------------------------------------------------------------------------------- /Basic200/T/LC419. Battleships in a Board.md: -------------------------------------------------------------------------------- 1 | ## LC 419. Battleships in a Board 2 | 3 | https://leetcode-cn.com/problems/battleships-in-a-board/ 4 | 5 | - [解法副标题](#思路-解法副标题) 6 | 7 | ### 思路 解法副标题 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var countBattleships = function(board) { 13 | 14 | 15 | let res = 0 16 | for(let i = 0; i 35 | 空间复杂度:O(1) 36 | -------------------------------------------------------------------------------- /Basic200/TODOLC50. Pow(x, n).md: -------------------------------------------------------------------------------- 1 | ## LC 50. Pow(x, n) 2 | 3 | ### 思路 4 | 5 | 普通递归 6 | 会爆栈 7 | 8 | ### 代码 9 | 10 | ```JavaScript 11 | var myPow = function(x, n) { 12 | if(n == 1) return x; 13 | if(n == 0) return 1; 14 | let neg = n < 0 ? true : false; 15 | n = Math.abs(n) 16 | // if(n == -1) return 1/x; 17 | let ans = (myPow(x, n-1) * x) 18 | // console.log(ans) 19 | return neg ? (1/ans) : (ans) 20 | 21 | } 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /Basic200/TwoPointers/LC3. Longest Substring Without Repeating Characters.md: -------------------------------------------------------------------------------- 1 | ## LC 3. Longest Substring Without Repeating Characters 2 | 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var lengthOfLongestSubstring = function(s) { 11 | let include = new Set(); 12 | let slow = 0, ans = 0 13 | 14 | for(let fast = 0; fast < s.length; fast++){ 15 | if(!include.has(s[fast])){ 16 | include.add(s[fast]) 17 | 18 | }else{ 19 | while(include.has(s[fast])){ 20 | include.delete(s[slow]) 21 | slow++ 22 | } 23 | include.add(s[fast]) 24 | } 25 | ans = Math.max(ans, include.size) 26 | } 27 | return ans; 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 34 | 时间复杂度:O(N)
35 | 空间复杂度:O(|\Sigma|∣Σ∣)|\Sigma|∣Σ∣ 表示字符集的大小 36 | -------------------------------------------------------------------------------- /Basic200/TwoPointers/LC904. Fruit Into Baskets.md: -------------------------------------------------------------------------------- 1 | ## LC 904. Fruit Into Baskets 2 | 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var totalFruit = function(tree) { 11 | const basket = new Array(tree.length).fill(0) 12 | let counter = 2; 13 | let ans = 0, slow = 0 14 | 15 | for(let i = 0; i < tree.length; i++){ 16 | let curType = tree[i] 17 | if(basket[curType] === 0) counter-- 18 | basket[curType] ++ 19 | 20 | while(counter < 0 && slow < i ){ 21 | basket[tree[slow]]-- 22 | if(basket[tree[slow]] == 0) counter++ 23 | slow++ 24 | } 25 | 26 | //果实个数 = 窗口大小 27 | ans = Math.max(ans, i - slow + 1) 28 | } 29 | return ans 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 36 | 时间复杂度:O(N)
37 | 空间复杂度:O(N)用了数组来保存菜篮子 Q_Q 其实用常数也可以 比如用一个 set 懒得写了... 38 | -------------------------------------------------------------------------------- /Basic200/TwoPointers/Template.md: -------------------------------------------------------------------------------- 1 | ## LC 2 | 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | 12 | ``` 13 | 14 | #### 复杂度分析 15 | 16 | 时间复杂度:
17 | 空间复杂度: 18 | -------------------------------------------------------------------------------- /Basic200/剑指 Offer 03. 数组中重复的数字.md: -------------------------------------------------------------------------------- 1 | ## 剑指 Offer 03. 数组中重复的数字 2 | 3 | https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/ 4 | 5 | ### 思路 6 | 7 | 用 set 如果包含了 就 return 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | var findRepeatNumber = function(nums) { 13 | let memo = new Set(); 14 | 15 | for(num of nums){ 16 | if(memo.has(num)) return num; 17 | memo.add(num) 18 | } 19 | }; 20 | 21 | ``` 22 | 23 | ### 复杂度分析 24 | 25 | 时间复杂度:O(N) 26 | 空间复杂度:O(N) 27 | -------------------------------------------------------------------------------- /Basic200/剑指 Offer 50. 第一个只出现一次的字符.md: -------------------------------------------------------------------------------- 1 | ## 剑指 Offer 50. 第一个只出现一次的字符 2 | 3 | https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/ 4 | 5 | ### 思路 6 | 7 | 哈希表 8 | 9 | ### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var firstUniqChar = function(s) { 13 | let memo = new Map(); 14 | for(char of s){ 15 | memo.set(char, ((memo.get(char) || 0 ) + 1)) 16 | } 17 | 18 | for(const[key, value] of memo){ 19 | if(value == 1) return key 20 | } 21 | 22 | return ' ' 23 | }; 24 | 25 | ``` 26 | 27 | ### 复杂度分析 28 | 29 | 时间复杂度:O(N) 30 | 空间复杂度:O(N) 31 | -------------------------------------------------------------------------------- /Basic200II/BinarySearch/LC153. Find Minimum in Rotated Sorted Array.md: -------------------------------------------------------------------------------- 1 | ## LC 153. Find Minimum in Rotated Sorted Array 2 | 3 | - [二分法-局部有序](#思路-二分法-局部有序) 4 | 5 | ### 思路 二分法-局部有序 6 | 利用二段性 7 | 注意是 l < r , 因为 r = m 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | 12 | var findMin = function(nums) { 13 | let l = 0, r = nums.length - 1 14 | //[1,2,3,4,5] 15 | //[2,3,4,5,1] !mid-> last increasing, ans = right 16 | //[3,4,5,1,2] otherwise, ans in [0...left] 17 | //[4,5,1,2,3] 18 | //[5,1,2,3,4] 19 | while(l < r){ 20 | const m = l + ((r - l ) >> 1) 21 | if(nums[m] < nums[r]) r = m 22 | else if(nums[m] > nums[r])l = m + 1 23 | } 24 | return nums[l] 25 | }; 26 | ``` 27 | 28 | #### 复杂度分析 29 | 时间复杂度:O(logn)
30 | 空间复杂度:O(1) -------------------------------------------------------------------------------- /Basic200II/BinarySearch/LC154. Find Minimum in Rotated Sorted Array II.md: -------------------------------------------------------------------------------- 1 | ## LC 154. Find Minimum in Rotated Sorted Array II 2 | 3 | - [二分法-局部有序](#思路-二分法-局部有序) 4 | 5 | ### 思路 二分法-局部有序 6 | 利用二段性 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var findMin = function(nums) { 11 | let l = 0, r = nums.length - 1 12 | //[4,5,6,7,0,1,4] 13 | //[0,1,4,4,5,6,7] 14 | //[4,4,0,4,4,4,4] 15 | while(l < r){ 16 | const m = l + ((r - l) >> 1) 17 | if(nums[m] === nums[r]) r-- 18 | else if(nums[m] > nums[r]) l = m + 1; 19 | else if(nums[m] < nums[r]) r = m 20 | // console.log(l, r, m) 21 | } 22 | return nums[l] 23 | }; 24 | 25 | ``` 26 | 27 | #### 复杂度分析 28 | 时间复杂度:
29 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/BinarySearch/LC162. Find Peak Element.md: -------------------------------------------------------------------------------- 1 | ## LC 162. Find Peak Element 2 | 3 | - [二分](#思路-二分) 4 | 5 | ### 思路 二分 6 | 多个局部有序?二段性? 7 | 如果 nums[m] < nums[m +1]那他肯定不是答案 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var findPeakElement = function(nums) { 12 | let l = 0, r = nums.length - 1 13 | 14 | while(l < r){ 15 | const m = l + ((r - l) >> 1) 16 | 17 | if(nums[m] < (nums[m + 1] || -Infinity)) l = m + 1 18 | else r = m 19 | } 20 | 21 | return l 22 | }; 23 | 24 | ``` 25 | 26 | #### 复杂度分析 27 | 时间复杂度:
28 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/BinarySearch/LC315. Count of Smaller Numbers After Self.md: -------------------------------------------------------------------------------- 1 | ## LC 315. Count of Smaller Numbers After Self 2 | https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/ 3 | 4 | 5 | - [解法副标题](#思路-解法副标题) 6 | 7 | ### 思路 解法副标题 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | 13 | 14 | ``` 15 | 16 | #### 复杂度分析 17 | 时间复杂度:
18 | 空间复杂度: 19 | 20 | 21 | 22 | - [暴力](#思路-暴力) 23 | 24 | ### 思路 暴力 25 | 26 | #### 代码 JavaScript 27 | 28 | ```JavaScript 29 | 30 | var countSmaller = function(nums) { 31 | const n = nums.length 32 | const count = new Array(n).fill(0) 33 | 34 | for(let i = 0; i < n; i++){ 35 | const num = nums[i] 36 | for(let j = i + 1; j < n; j++){ 37 | if(num > nums[j]) count[i]++ 38 | } 39 | } 40 | 41 | return count 42 | }; 43 | ``` 44 | 45 | #### 复杂度分析 46 | 时间复杂度:
47 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/BinarySearch/LC35. Search Insert Position.md: -------------------------------------------------------------------------------- 1 | ## LC 35. Search Insert Position 2 | 3 | https://leetcode-cn.com/problems/search-insert-position/ 4 | 5 | - [二分搜索](#思路-二分搜索) 6 | 7 | ### 思路 二分搜索 8 | 9 | 二分搜索-寻找最左插入位置 10 | 11 | #### 代码 JavaScript 12 | 13 | ```JavaScript 14 | var searchInsert = function(nums, target) { 15 | let left = 0, right = nums.length - 1 16 | 17 | while(left <= right){ 18 | const mid = left + ((right - left) >> 1) 19 | 20 | if(target == nums[mid]){ 21 | right = mid - 1 22 | }else if(target > nums[mid]){ 23 | left = mid + 1 24 | }else{ 25 | right = mid - 1 26 | } 27 | } 28 | 29 | return left; 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 36 | 时间复杂度:O(logN)
37 | 空间复杂度:O(1) 38 | -------------------------------------------------------------------------------- /Basic200II/BinarySearch/LC528. 按权重随机选择.md: -------------------------------------------------------------------------------- 1 | ## LC 528. 按权重随机选择 2 | https://leetcode-cn.com/problems/random-pick-with-weight/ 3 | - [二分](#思路-二分) 4 | 5 | ### 思路 二分 6 | 前缀和使得概率变成了二分? 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | var Solution = function(w) { 12 | this.prefix = [] 13 | let tt = 0 14 | for(const n of w){ 15 | tt += n 16 | this.prefix.push(tt) 17 | } 18 | this.tt = tt 19 | }; 20 | 21 | /** 22 | * @return {number} 23 | */ 24 | Solution.prototype.pickIndex = function() { 25 | //寻找第一个大于等于x的数字 26 | let l = 0, r = this.prefix.length - 1 27 | let x = Math.random() * this.tt 28 | while(l <= r){ 29 | const m = l + ((r - l) >> 1) 30 | 31 | if(this.prefix[m] >= x) r = m - 1 32 | else l = m + 1 33 | } 34 | return l 35 | }; 36 | ``` 37 | 38 | #### 复杂度分析 39 | 时间复杂度:
40 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/DP/路径问题/LC64. Minimum Path Sum.md: -------------------------------------------------------------------------------- 1 | ## LC 64. Minimum Path Sum 2 | 3 | - [朴素dp](#思路-朴素dp) 4 | 5 | ### 思路 朴素dp 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var minPathSum = function(grid) { 11 | const m = grid.length 12 | const n = grid[0].length 13 | 14 | const dp = Array.from({length: m}).map(() => Array.from({length: n}).fill(0)) 15 | dp[0][0] = grid[0][0] 16 | for(let i = 0; i < dp.length; i++){ 17 | for(let j = 0; j < dp[0].length; j++){ 18 | if(i > 0 && j > 0) dp[i][j] = Math.min(dp[i-1][j], dp[i][j - 1]) + grid[i][j] 19 | else if(i > 0) dp[i][j] = dp[i-1][j] + grid[i][j] 20 | else if(j > 0) dp[i][j] = dp[i][j - 1] + grid[i][j] 21 | } 22 | } 23 | 24 | return dp[m-1][n-1] 25 | 26 | }; 27 | 28 | ``` 29 | 30 | #### 复杂度分析 31 | 时间复杂度:
32 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/DP/路径问题/LC91. Decode Ways.md: -------------------------------------------------------------------------------- 1 | ## LC 91. Decode Ways 2 | 3 | https://leetcode-cn.com/problems/decode-ways/ 4 | ### 思路 动态规划 5 | 分析出来转移方程,并且通过添加空格哨兵减少判断。 6 | REVIEW 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var numDecodings = function(s) { 11 | const n = s.length 12 | s = ' ' + s 13 | const dp = new Array(n + 1).fill(0) 14 | dp[0] = 1 15 | 16 | 17 | // 1 2 18 | // 1 2 1 -> 1,2,1; 12, 1; 1,21; 19 | 20 | 21 | for(let i = 1; i < dp.length; i++){ 22 | let a = Number(s[i]) 23 | let b = Number(s[i-1]) * 10 + a 24 | 25 | if(a >= 1 && a <= 9){ 26 | dp[i] = dp[i - 1] 27 | } 28 | if(b >= 10 && b <= 26){ 29 | dp[i] += dp[i -2] 30 | } 31 | } 32 | // console.log(dp) 33 | return dp[n] 34 | }; 35 | 36 | ``` 37 | 38 | #### 复杂度分析 39 | 时间复杂度:
40 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/DP线性/打家劫舍/LC198. House Robber.md: -------------------------------------------------------------------------------- 1 | ## LC 198. House Robber 2 | https://leetcode-cn.com/problems/house-robber/ 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | 动态规划 - 单串 - 打家劫舍 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var rob = function(nums) { 11 | //dp[i] 走到i的时候的最大值 12 | const dp = new Array(nums.length).fill(0) 13 | let max = 0 14 | 15 | for(let i = 0; i < nums.length; i++){ 16 | dp[i] = Math.max(nums[i] + (dp[i - 2] || 0), (dp[i - 1] || 0)) 17 | max = Math.max(dp[i], max) 18 | } 19 | 20 | return max 21 | }; 22 | 23 | ``` 24 | 25 | #### 复杂度分析 26 | 时间复杂度:O(N)
27 | 空间复杂度:O(N) 28 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/DP线性/打家劫舍/LC213. House Robber II.md: -------------------------------------------------------------------------------- 1 | ## LC 213. House Robber II 2 | https://leetcode-cn.com/problems/house-robber-ii/ 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | 动态规划 - 单串 - 打家劫舍 7 | 这是个环,那么这个环转化成一般打家劫舍问题就是 8 | 抢劫这个nums的[1:-1] 和 抢劫这个环的[0:-2] 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var rob = function(nums) { 13 | if(nums.length == 0)return 0 14 | if(nums.length == 1)return nums[0] 15 | let robFirst = nums.slice(0, nums.length-1) 16 | let robLast = nums.slice(1) 17 | 18 | return Math.max(myrob(robFirst), myrob(robLast)) 19 | 20 | }; 21 | 22 | var myrob = function(nums){ 23 | const dp = new Array(nums.length + 1).fill(0) 24 | 25 | let ret = 0 26 | 27 | for(let i = 0; i < nums.length; i++){ 28 | dp[i] = Math.max(nums[i] + (dp[i - 2] || 0) , (dp[i - 1] || 0)) 29 | ret = Math.max(dp[i]) 30 | } 31 | 32 | return ret 33 | } 34 | 35 | ``` 36 | 37 | #### 复杂度分析 38 | 时间复杂度:O(N)
39 | 空间复杂度:O(N) 40 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/LC1035. Uncrossed Lines.md: -------------------------------------------------------------------------------- 1 | ## LC 1035. Uncrossed Lines 2 | 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | 7 | 最长公共子序列换皮 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var maxUncrossedLines = function(nums1, nums2) { 13 | const dp = Array.from({length: nums1.length + 1}).map(() =>Array.from({length: nums2.length + 1}).fill(0)) 14 | let ans = 0 15 | for(let i = 1; i <= nums1.length; i++){ 16 | for(let j = 1; j <= nums2.length; j++){ 17 | if(nums1[i - 1] == nums2[j - 1]){ 18 | dp[i][j] = dp[i-1][j - 1] + 1 19 | }else{ 20 | dp[i][j] = Math.max(dp[i-1][j], dp[i][j - 1]) 21 | } 22 | ans = Math.max(ans, dp[i][j]) 23 | } 24 | } 25 | 26 | return ans; 27 | }; 28 | 29 | ``` 30 | 31 | #### 复杂度分析 32 | 33 | 时间复杂度:O(MN)
34 | 空间复杂度:O(MN) 35 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/LC139. Word Break.md: -------------------------------------------------------------------------------- 1 | ## LC 139. Word Break 2 | 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | 7 | 动态规划 划分 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var wordBreak = function(s, wordDict) { 13 | const dic = new Set(wordDict) 14 | //dp长度为i的s是否能被segment 15 | const dp = new Array(s.length +1).fill(false) 16 | dp[0] = true 17 | for(let i = 1; i <= s.length; i++){ 18 | //注意这里是倒着遍历的,因为只需要找新增的部分 19 | for(let j = i-1; j >= 0; j--){ 20 | let curWord = s.slice(j, i) 21 | if(dic.has(curWord) && dp[j]){ 22 | dp[i] = true 23 | break; 24 | } 25 | } 26 | } 27 | 28 | return dp[s.length] 29 | }; 30 | 31 | ``` 32 | 33 | #### 复杂度分析 34 | 35 | 时间复杂度:
36 | 空间复杂度: 37 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/LC292. Nim Game.md: -------------------------------------------------------------------------------- 1 | ## LC 292. Nim Game 2 | 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | 7 | 动态规划 博弈论 8 | review 9 | 10 | #### 代码 JavaScript 11 | 12 | ```JavaScript 13 | var canWinNim = function(n) { 14 | return( n % 4 != 0) 15 | }; 16 | 17 | ``` 18 | 19 | #### 复杂度分析 20 | 21 | 时间复杂度:
22 | 空间复杂度: 23 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/LC3. Longest Substring Without Repeating Characters.md: -------------------------------------------------------------------------------- 1 | ## LC 3. Longest Substring Without Repeating Characters 2 | 3 | - [双指针滑动窗口](#思路-双指针滑动窗口) 4 | 5 | ### 思路 双指针滑动窗口 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var lengthOfLongestSubstring = function(s) { 11 | const memo = new Set() 12 | let ans = 0 13 | let slow = 0; 14 | for(let fast = 0; fast 32 | 空间复杂度:O(longest repeating string length) 33 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/LC357. Count Numbers with Unique Digits.md: -------------------------------------------------------------------------------- 1 | ## LC 357. Count Numbers with Unique Digits 2 | 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | 7 | 动态规划 数位型 8 | 数学推理? 9 | review 10 | 11 | #### 代码 JavaScript 12 | 13 | ```JavaScript 14 | 15 | var countNumbersWithUniqueDigits = function(n) { 16 | const dp = new Array(n + 1).fill(0) 17 | 18 | for(let i = 2; i<= n; i++){ 19 | dp[i] = dp[i-1]*10 + (9 * Math.pow(10, i-2) - dp[i-1]) * (i-1) 20 | 21 | } 22 | 23 | let sum = 0 24 | for(const x of dp){ 25 | sum +=x 26 | } 27 | return Math.pow(10, n) - sum 28 | }; 29 | ``` 30 | 31 | #### 复杂度分析 32 | 33 | 时间复杂度:
34 | 空间复杂度: 35 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/LC63. Unique Paths II.md: -------------------------------------------------------------------------------- 1 | ## LC 63. Unique Paths II 2 | 3 | https://leetcode-cn.com/problems/unique-paths-ii/ 4 | 5 | - [动态规划+滚动数组](#思路-动态规划+滚动数组) 6 | 7 | ### 思路 动态规划+滚动数组 8 | 9 | 滚动数组要记得给 base case 留地方 10 | 11 | #### 代码 JavaScript 12 | 13 | ```JavaScript 14 | var uniquePathsWithObstacles = function(obstacleGrid) { 15 | const dp = new Array(obstacleGrid[0].length +1).fill(0) 16 | dp[1] = 1 17 | for(let i = 1; i <= obstacleGrid.length; i++){ 18 | for(let j = 1; j <= obstacleGrid[0].length; j++){ 19 | if(obstacleGrid[i-1][j - 1] == 0){ 20 | dp[j] += dp[j - 1] 21 | }else{ 22 | dp[j] = 0 23 | } 24 | 25 | } 26 | // console.log(dp) 27 | // [ 0, 1, 1, 1 ] 28 | // [ 0, 1, 0, 1 ] 29 | // [ 0, 1, 1, 2 ] 30 | } 31 | return dp[obstacleGrid[0].length] 32 | }; 33 | 34 | ``` 35 | 36 | #### 复杂度分析 37 | 38 | 时间复杂度:O(NM)
39 | 空间复杂度:O(1) 40 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/LC646. Maximum Length of Pair Chain.md: -------------------------------------------------------------------------------- 1 | ## LC 646. Maximum Length of Pair Chain 2 | 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | 7 | 最长上升子序列换皮 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var findLongestChain = function(pairs) { 13 | // dp[i] = 选择i的时候从[0..i]能形成的最长上升子序列 14 | pairs.sort((a,b) => a[0] - b[0]) 15 | 16 | dp = new Array(pairs.length).fill(1) 17 | 18 | for(let i = 0; i < pairs.length; i++){ 19 | for(j = 0; j < i; j++){ 20 | if(pairs[i][0] > pairs[j][1]){ 21 | dp[i] = Math.max(dp[i], dp[j] + 1) 22 | } 23 | } 24 | } 25 | 26 | return Math.max(...dp) 27 | }; 28 | 29 | ``` 30 | 31 | #### 复杂度分析 32 | 33 | 时间复杂度:O(N^2)
34 | 空间复杂度:O(N) 35 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/LC70. Climbing Stairs.md: -------------------------------------------------------------------------------- 1 | ## LC 70. Climbing Stairs 2 | 3 | https://leetcode-cn.com/problems/climbing-stairs/ 4 | 5 | - [动态规划](#思路-动态规划) 6 | 7 | ### 思路 动态规划 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var climbStairs = function(n) { 13 | const dp = new Array(n + 1) 14 | dp[1] = 1 15 | dp[2] = 2 16 | for(let i = 3; i <= n; i++){ 17 | dp[i] = dp[i - 1] + dp[i - 2] 18 | } 19 | // console.log(dp) 20 | return dp[n] 21 | }; 22 | 23 | ``` 24 | 25 | #### 复杂度分析 26 | 27 | 时间复杂度:O(N)
28 | 空间复杂度:O(N) 29 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/LC837. New 21 Game.md: -------------------------------------------------------------------------------- 1 | ## LC 837. New 21 Game 2 | 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | 7 | [学习](https://leetcode-cn.com/problems/new-21-game/solution/huan-you-bi-zhe-geng-jian-dan-de-ti-jie-ma-tian-ge/) 8 | 动态规划-概率 9 | Review 10 | 11 | #### 代码 JavaScript 12 | 13 | ```JavaScript 14 | var new21Game = function(n, k, maxPts) { 15 | const dp = new Array(k + maxPts) 16 | let s = 0 17 | 18 | for(let i = k; i < k + maxPts; i++){ 19 | if(i <= n) dp[i] = 1 20 | else dp[i] = 0 21 | s+= dp[i] 22 | } 23 | 24 | for(let i = k - 1; i >= 0; i--){ 25 | dp[i] = s /maxPts 26 | s = s - dp[i + maxPts] + dp[i] 27 | } 28 | 29 | return dp[0] 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 36 | 时间复杂度:O(K+maxPts)
37 | 空间复杂度:O(K+maxPts) 38 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/Template.md: -------------------------------------------------------------------------------- 1 | ## LC 2 | 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | 12 | ``` 13 | 14 | #### 复杂度分析 15 | 时间复杂度:
16 | 空间复杂度: 17 | -------------------------------------------------------------------------------- /Basic200II/DynamicProgramming/面试题 17.13. 恢复空格.md: -------------------------------------------------------------------------------- 1 | ## 面试题 17.13. 恢复空格 2 | 3 | https://leetcode-cn.com/problems/re-space-lcci/ 4 | 5 | - [动态规划](#思路-动态规划) 6 | 7 | ### 思路 动态规划 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var respace = function(dictionary, sentence) { 13 | const dic = new Set(dictionary) 14 | const n = sentence.length 15 | const dp = Array.from({length: n + 1}) //前i个字符最少字符未匹配数 16 | dp[0] = 0//base case,此处 字符长度为0 17 | 18 | for(let i = 1; i <= n; i++){ 19 | dp[i] = dp[i - 1] + 1 20 | for(let j = i - 1; j >= 0; j--){ 21 | word = sentence.slice(j, i) 22 | 23 | if(dic.has(word)){ 24 | dp[i] = Math.min(dp[i], dp[j]) 25 | }else{ 26 | dp[i] = Math.min(dp[i], dp[j] + i - j) 27 | } 28 | } 29 | } 30 | return dp[n] 31 | }; 32 | 33 | ``` 34 | 35 | #### 复杂度分析 36 | 37 | 时间复杂度:O(N^2)
38 | 空间复杂度:O(N) 39 | -------------------------------------------------------------------------------- /Basic200II/G/LC1110. Delete Nodes And Return Forest.md: -------------------------------------------------------------------------------- 1 | ## LC 1110. Delete Nodes And Return Forest 2 | 3 | - [后序遍历](#思路-后序遍历) 4 | 5 | ### 思路 后序遍历 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var delNodes = function(root, to_delete) { 11 | 12 | const helper = (node)=> { 13 | if(!node) return node; 14 | node.left = helper(node.left) 15 | node.right = helper(node.right) 16 | 17 | if(d.has(node.val)){ 18 | node.left && forest.push(node.left) 19 | node.right && forest.push(node.right) 20 | node = null; 21 | } 22 | 23 | return node; 24 | } 25 | 26 | 27 | 28 | const d = new Set(to_delete); 29 | const forest = [] 30 | 31 | root = helper(root) 32 | if(root) forest.push(root) 33 | return forest 34 | }; 35 | 36 | ``` 37 | 38 | #### 复杂度分析 39 | 时间复杂度:
40 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/G/LC1423. Maximum Points You Can Obtain from Cards.md: -------------------------------------------------------------------------------- 1 | ## LC 1423. Maximum Points You Can Obtain from Cards 2 | 3 | - [滑动窗口](#思路-滑动窗口) 4 | 5 | ### 思路 滑动窗口 6 | 转换题意: 7 | 最大拿走的点数 = 总的点数 - 剩下的点数。 8 | 剩下的点数可以看做是一个滑动窗口,让剩下的点数最小就行。 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | 13 | var maxScore = function(cardPoints, k) { 14 | const n = cardPoints.length 15 | const sum = cardPoints.reduce((a,e) => a + e) 16 | let curWindow = 0 17 | for(let i = 0; i < n - k; i++){ 18 | curWindow += cardPoints[i] 19 | } 20 | 21 | let ret = curWindow 22 | for(let i = n - k, j = 0; i < n; i++, j++){ 23 | curWindow += cardPoints[i] 24 | curWindow -= cardPoints[j] 25 | ret = Math.min(ret, curWindow) 26 | } 27 | 28 | return sum - ret 29 | 30 | }; 31 | ``` 32 | 33 | #### 复杂度分析 34 | 时间复杂度:
35 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/G/LC1525. Number of Good Ways to Split a String.md: -------------------------------------------------------------------------------- 1 | ## LC 1525. Number of Good Ways to Split a String 2 | 3 | - [哈希表](#思路-哈希表) 4 | 5 | ### 思路 哈希表 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var numSplits = function(s) { 11 | const window1 = new Map 12 | const window2 = new Map 13 | for(const c of s){ 14 | window1.set(c, (window1.get(c) || 0) + 1) 15 | } 16 | 17 | let ret = 0 18 | for(const c of s){ 19 | window1.set(c, window1.get(c) - 1) 20 | if(window1.get(c) === 0) window1.delete(c) 21 | 22 | window2.set(c, (window2.get(c) || 0) + 1) 23 | 24 | if(window1.size === window2.size) ret++ 25 | } 26 | 27 | return ret 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 时间复杂度:O(N)
34 | 空间复杂度:O(N) -------------------------------------------------------------------------------- /Basic200II/G/LC1526. Minimum Number of Increments on Subarrays to Form a Target Array.md: -------------------------------------------------------------------------------- 1 | ## LC 1526. Minimum Number of Increments on Subarrays to Form a Target Array 2 | 3 | 4 | ### 思路 动态规划 5 | 如果右边的更大,那么需要累加`target[i] - target[i - 1]`次,不然的话,不需要更多操作次数。 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | 10 | var minNumberOperations = function(target) { 11 | const n = target.length 12 | if(n == 0) return 0 13 | const dp = new Array(n) 14 | dp[0] = target[0] 15 | for(let i = 1; i < n; i++){ 16 | if(target[i] <= target[i - 1]) dp[i] = dp[i - 1]; 17 | else dp[i] = dp[i - 1] + target[i] - target[i - 1] 18 | } 19 | 20 | return dp[n - 1] 21 | }; 22 | ``` 23 | 24 | #### 复杂度分析 25 | 时间复杂度:
26 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/G/LC652. Find Duplicate Subtrees.md: -------------------------------------------------------------------------------- 1 | ## LC 652. Find Duplicate Subtrees 2 | https://leetcode-cn.com/problems/find-duplicate-subtrees/ 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var findDuplicateSubtrees = function(root) { 11 | const res = [], vis = new Map; 12 | const traversal = (root)=>{ 13 | if(!root) return 'X' 14 | const left = traversal(root.left) 15 | const right = traversal(root.right) 16 | const str = `${left},${right},${root.val}` 17 | const count = vis.get(str) 18 | if(count === 1) res.push(root) 19 | vis.set(str, (vis.get(str) || 0) + 1) 20 | return str 21 | } 22 | traversal(root) 23 | return res; 24 | 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 时间复杂度:
31 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC100. Same Tree.md: -------------------------------------------------------------------------------- 1 | ## LC 100. Same Tree 2 | https://leetcode-cn.com/problems/same-tree/ 3 | 4 | #### 代码 JavaScript 5 | 6 | ```JavaScript 7 | 8 | var isSameTree = function(p, q) { 9 | if(!p && !q) return true 10 | if(!p || !q) return false 11 | if(p.val != q.val) return false 12 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right) 13 | }; 14 | ``` 15 | 16 | #### 复杂度分析 17 | 时间复杂度:
18 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC1004. Max Consecutive Ones III.md: -------------------------------------------------------------------------------- 1 | ## LC 1004. Max Consecutive Ones III 2 | 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 求最大窗口的时候好像。。。不需要while,只要if就可以了。 7 | 如果用while需要一个记录最长的变量。 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var longestOnes = function(nums, k) { 12 | let l = 0, r = 0 13 | let countzero = 0 14 | while(r < nums.length){ 15 | const c = nums[r] 16 | if(c === 0) countzero++ 17 | 18 | if(countzero > k && l <= r){ 19 | const cl = nums[l] 20 | if(cl === 0) countzero-- 21 | 22 | l++ 23 | } 24 | r++ 25 | } 26 | 27 | return r - l 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 时间复杂度:O(n)
34 | 空间复杂度:O(1) -------------------------------------------------------------------------------- /Basic200II/LC101. Symmetric Tree.md: -------------------------------------------------------------------------------- 1 | ## LC 101. Symmetric Tree 2 | 3 | ### 思路 解法副标题 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var isSymmetric = function(root) { 9 | 10 | const checker = function(p,q){ 11 | if(!p && !q) return true 12 | if(!p || !q) return false 13 | if(p.val != q.val) return false 14 | 15 | return checker(p.left, q.right) && checker(p.right, q.left) 16 | } 17 | 18 | 19 | 20 | if(!root) return true 21 | else return checker(root.left, root.right) 22 | 23 | 24 | }; 25 | 26 | ``` 27 | 28 | #### 复杂度分析 29 | 时间复杂度:
30 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC102. Binary Tree Level Order Traversal.md: -------------------------------------------------------------------------------- 1 | ## LC 102. Binary Tree Level Order Traversal 2 | 3 | ### 思路 解法副标题 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var levelOrder = function(root) { 9 | const ret = [] 10 | 11 | if(!root) return ret 12 | 13 | const queue = [root] 14 | 15 | while(queue.length){ 16 | const levelRes = [] 17 | const levelSize = queue.length 18 | 19 | for(let i = 0; i < levelSize; i++){ 20 | const node = queue.shift() 21 | levelRes.push(node.val) 22 | node.left && queue.push(node.left) 23 | node.right && queue.push(node.right) 24 | } 25 | ret.push(levelRes) 26 | } 27 | return ret; 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 时间复杂度:
34 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC103. Binary Tree Zigzag Level Order Traversal.md: -------------------------------------------------------------------------------- 1 | ## LC 103. Binary Tree Zigzag Level Order Traversal 2 | https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/ 3 | ### 思路 解法副标题 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var zigzagLevelOrder = function(root) { 9 | const ret = [] 10 | if(!root) return ret 11 | 12 | const queue = [root] 13 | let level = 0 14 | while(queue.length){ 15 | let levelRes = [] 16 | const levelSize = queue.length 17 | for(let i = 0 ; i < levelSize; i++){ 18 | const node = queue.shift() 19 | 20 | levelRes.push(node.val) 21 | node.left && queue.push(node.left) 22 | node.right && queue.push(node.right) 23 | } 24 | if(level % 2 == 0) ret.push(levelRes) 25 | else ret.push(levelRes.reverse()) 26 | level++ 27 | } 28 | 29 | return ret 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 时间复杂度:
36 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC104. Maximum Depth of Binary Tree.md: -------------------------------------------------------------------------------- 1 | ## LC 104. Maximum Depth of Binary Tree 2 | #### 代码 JavaScript 3 | 4 | ```JavaScript 5 | 6 | var maxDepth = function(root) { 7 | let ret = 0 8 | if(!root) return ret 9 | 10 | const queue = [root] 11 | 12 | while(queue.length){ 13 | const levelSize = queue.length 14 | ret++ 15 | for(let i = 0; i < levelSize; i++){ 16 | const node = queue.shift() 17 | 18 | node.left && queue.push(node.left) 19 | node.right && queue.push(node.right) 20 | } 21 | } 22 | 23 | return ret 24 | }; 25 | ``` 26 | 27 | #### 复杂度分析 28 | 时间复杂度:
29 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC1052. Grumpy Bookstore Owner.md: -------------------------------------------------------------------------------- 1 | ## LC 1052. Grumpy Bookstore Owner 2 | 3 | - [滑动窗口](#思路-滑动窗口) 4 | 5 | ### 思路 滑动窗口 6 | 简化问题: 7 | 首先把不生气的时候的顾客求出来,并且从顾客冲剔除。 8 | 这个时候就求能影响顾客的最大值,给定一定的grump值。 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var maxSatisfied = function(customers, grumpy, minutes) { 13 | let ans = 0 14 | let cur = 0, max = 0 15 | const n = customers.length 16 | for(let i = 0; i < n; i++){ 17 | if(grumpy[i] === 0){ 18 | ans+= customers[i] 19 | customers[i] = 0 20 | } 21 | } 22 | 23 | for(let i = 0, j = 0; i < n; i++){ 24 | cur += customers[i] 25 | if(i - j + 1 > minutes){ 26 | cur -= customers[j] 27 | j++ 28 | } 29 | 30 | max = Math.max(max, cur) 31 | } 32 | 33 | return ans + max 34 | }; 35 | 36 | ``` 37 | 38 | #### 复杂度分析 39 | 时间复杂度:
40 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC107. Binary Tree Level Order Traversal II.md: -------------------------------------------------------------------------------- 1 | ## LC 107. Binary Tree Level Order Traversal II 2 | https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/ 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | var levelOrderBottom = function(root) { 12 | const ret = [] 13 | if(!root) return ret 14 | 15 | const queue = [root] 16 | 17 | while(queue.length){ 18 | const levelSize = queue.length 19 | const levelRes = [] 20 | for(let i = 0; i < levelSize; i++){ 21 | const node = queue.shift() 22 | 23 | levelRes.push(node.val) 24 | node.left && queue.push(node.left) 25 | node.right && queue.push(node.right) 26 | } 27 | ret.unshift(levelRes) 28 | } 29 | 30 | return ret 31 | }; 32 | ``` 33 | 34 | #### 复杂度分析 35 | 时间复杂度:
36 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC108. Convert Sorted Array to Binary Search Tree.md: -------------------------------------------------------------------------------- 1 | ## LC 108. Convert Sorted Array to Binary Search Tree 2 | 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var sortedArrayToBST = function(nums) { 11 | if(nums.length == 0) return null 12 | if(nums.length == 1) return new TreeNode(nums[0]) 13 | const rootIndex = Math.floor(nums.length / 2) 14 | const root = new TreeNode(nums[rootIndex]) 15 | root.left = sortedArrayToBST(nums.slice(0, rootIndex)) 16 | root.right = sortedArrayToBST(nums.slice(rootIndex + 1)) 17 | return root 18 | }; 19 | 20 | ``` 21 | 22 | #### 复杂度分析 23 | 时间复杂度: ON
24 | 空间复杂度::O(\log n)O(logn),其中 nn 是数组的长度。空间复杂度不考虑返回值,因此空间复杂度主要取决于递归栈的深度,递归栈的深度是 O(\log n)O(logn)。 -------------------------------------------------------------------------------- /Basic200II/LC11. Container With Most Water.md: -------------------------------------------------------------------------------- 1 | ## LC 11. Container With Most Water 2 | 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var maxArea = function(height) { 11 | let left = 0, right = height.length - 1 12 | let area = 0 13 | while(left < right){ 14 | let width = right - left 15 | let h = Math.min(height[right], height[left]) 16 | if(h == height[right]){ 17 | right-- 18 | }else{ 19 | left++ 20 | } 21 | area = Math.max(area, width * h) 22 | } 23 | 24 | return area; 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 31 | 时间复杂度:O(N)
32 | 空间复杂度:O(1) 33 | -------------------------------------------------------------------------------- /Basic200II/LC113. Path Sum II.md: -------------------------------------------------------------------------------- 1 | ## LC 113. Path Sum II 2 | https://leetcode-cn.com/problems/path-sum-ii/ 3 | 4 | ### 思路 回溯 5 | 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var pathSum = function(root, targetSum) { 10 | const res = [] 11 | if(!root)return res 12 | 13 | var bt = (path, curSum, node) => { 14 | if(!node.left && !node.right){ 15 | if(curSum == targetSum) res.push(path.slice()) 16 | return 17 | } 18 | 19 | if(node.left) bt(path.concat(node.left.val), curSum + node.left.val, node.left) 20 | if(node.right) bt(path.concat(node.right.val), curSum + node.right.val, node.right) 21 | } 22 | 23 | bt([root.val], root.val, root) 24 | return res 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 时间复杂度: O n^2 B 是节点数,且每一个都符合要求,有n个路径,且每个路径节点数也为On 31 | 空间复杂度:O n 栈中元素个数不会超过节点数个数 32 | 33 | 一般是O(n),答案最多有O(n^2)个数,每个都要push到res里去 -------------------------------------------------------------------------------- /Basic200II/LC117. Populating Next Right Pointers in Each Node II.md: -------------------------------------------------------------------------------- 1 | ## LC 117. Populating Next Right Pointers in Each Node II 2 | https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/ 3 | 4 | ### 思路 BFS 5 | 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var connect = function(root) { 10 | if(!root) return root 11 | const queue = [root] 12 | while(queue.length){ 13 | const size = queue.length 14 | const temp = [] 15 | for(let i = 0; i < size; i++){ 16 | const node= queue.shift() 17 | temp.push(node) 18 | node.left && queue.push(node.left) 19 | node.right && queue.push(node.right) 20 | } 21 | for(let i = 0; i < size - 1; i++){ 22 | temp[i].next = temp[i + 1] 23 | } 24 | } 25 | return root 26 | }; 27 | 28 | ``` 29 | 30 | #### 复杂度分析 31 | 时间复杂度:
32 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC118. Pascal's Triangle.md: -------------------------------------------------------------------------------- 1 | ## LC 118. Pascal's Triangle 2 | 3 | ### 思路 解法副标题 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var generate = function(numRows) { 9 | if(numRows == 1) return [[1]] 10 | if(numRows == 2) return [[1], [1,1]] 11 | 12 | const res = generate(numRows - 1) 13 | const prerow = res[res.length - 1] 14 | const row = [] 15 | for(let i = 0; i <= prerow.length; i++){ 16 | const temp = (prerow[i] || 0) + (prerow[i - 1] || 0) 17 | row.push(temp) 18 | } 19 | res.push(row) 20 | return res 21 | }; 22 | 23 | 24 | ``` 25 | 26 | #### 复杂度分析 27 | 时间复杂度:
28 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC119. Pascal's Triangle II.md: -------------------------------------------------------------------------------- 1 | ## LC 119. Pascal's Triangle II 2 | 3 | - [DP动态规划](#思路-DP动态规划) 4 | 5 | ### 思路 DP动态规划 6 | 注意里层要倒序遍历,因为要`f[j -1]`也是上一层的旧值才可以。如果是正序遍历的话,会变成现在的f[i]更新的值依赖于已经被更新的f[j-1],是错的 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var getRow = function(rowIndex) { 11 | const f = new Array(rowIndex + 1) 12 | f[0] = 1 13 | 14 | for(let k = 1; k <= rowIndex; k++){ 15 | f[0] = f[k] = 1 16 | for(let j = k - 1; j >= 1; j--){ 17 | f[j] = f[j] + f[j - 1] 18 | } 19 | } 20 | 21 | 22 | return f 23 | }; 24 | 25 | ``` 26 | 27 | #### 复杂度分析 28 | 时间复杂度:
29 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC124. Binary Tree Maximum Path Sum.md: -------------------------------------------------------------------------------- 1 | ## LC 124. Binary Tree Maximum Path Sum 2 | https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/ 3 | - [递归](#思路-递归) 4 | 5 | ### 思路 递归 6 | 注意分析,对于每一个节点来说,他可以是root(这时候左右都能选), 也可以是provider(这时候左和右只能选一个) 7 | 如果他provide的数值小于0(就是会起反作用),那么也可以不选 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | const maxPathSum = (root) => { 12 | let maxSum = Number.MIN_SAFE_INTEGER; // 最大路径和 13 | 14 | const dfs = (root) => { 15 | if(!root) return 0 16 | 17 | const left = dfs(root.left) 18 | const right = dfs(root.right) 19 | 20 | const curRootasStart = left + right + root.val 21 | maxSum = Math.max(maxSum, curRootasStart) 22 | const providing = Math.max(left, right) + root.val 23 | return providing > 0 ? providing : 0 24 | }; 25 | 26 | dfs(root); // 递归的入口 27 | return maxSum; 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 时间复杂度:
34 | 空间复杂度: 35 | -------------------------------------------------------------------------------- /Basic200II/LC134. Gas Station.md: -------------------------------------------------------------------------------- 1 | ## LC 134. Gas Station 2 | https://leetcode-cn.com/problems/gas-station/ 3 | - [贪心](#思路-贪心) 4 | 5 | ### 思路 贪心 6 | 如果总油量大于总消耗那么一定可以跑完一圈。 7 | 每个加油站的profit是 gas[i] - cost[i],如果小于0,说明起点一定不在[0,i]; 8 | 如果总油量大于总消耗,那么在负数的i后面一定有更大的正数i。 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var canCompleteCircuit = function(gas, cost) { 13 | let curSum = 0; 14 | let totalSum = 0 15 | let start = 0 16 | 17 | for(let i = 0; i < gas.length;i++){ 18 | curSum += gas[i] - cost[i]; 19 | totalSum += gas[i] - cost[i] 20 | if(curSum < 0){ 21 | start = i + 1 22 | curSum = 0 23 | } 24 | } 25 | if(totalSum < 0) return -1; 26 | return start 27 | }; 28 | 29 | ``` 30 | 31 | #### 复杂度分析 32 | 时间复杂度:O(n)
33 | 空间复杂度:O(1) 34 | 35 | -------------------------------------------------------------------------------- /Basic200II/LC142. Linked List Cycle II.md: -------------------------------------------------------------------------------- 1 | ## LC 142. Linked List Cycle II 2 | https://leetcode-cn.com/problems/linked-list-cycle-ii/ 3 | - [floyds](#思路-floyds) 4 | 5 | ### 思路 floyds 6 | 注意floyds一定要两个都从起点出发才行。 7 | 8 | 判断是否有环的时候快慢指针一定会相遇,但相遇不一定在入口。 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var detectCycle = function(head) { 13 | if(!head || !head.next || !head.next.next) return null 14 | 15 | let slow = head, fast = head; 16 | do{ 17 | if(!fast || !fast.next) return null; 18 | fast = fast.next.next 19 | slow = slow.next 20 | }while(fast != slow) 21 | 22 | 23 | fast = head 24 | 25 | while(slow != fast){ 26 | fast = fast.next 27 | slow = slow.next 28 | } 29 | 30 | return slow 31 | }; 32 | 33 | ``` 34 | 35 | #### 复杂度分析 36 | 时间复杂度:
37 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC147. Insertion Sort List.md: -------------------------------------------------------------------------------- 1 | ## LC 147. Insertion Sort List 2 | 3 | ### 思路 解法副标题 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var insertionSortList = function(head) { 9 | const d = new ListNode(-1, head) 10 | let cur = head, pre = d, target = null 11 | while(cur && cur.next){ 12 | if(cur.val <= cur.next.val){ 13 | cur = cur.next 14 | }else{ 15 | target = cur.next 16 | cur.next = cur.next.next 17 | 18 | pre = d 19 | while(pre.next.val <= target.val){ 20 | pre = pre.next 21 | } 22 | target.next = pre.next 23 | pre.next = target 24 | } 25 | } 26 | 27 | return d.next 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 时间复杂度:
34 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC151. Reverse Words in a String.md: -------------------------------------------------------------------------------- 1 | ## LC 151. Reverse Words in a String 2 | 3 | - [朴素双指针](#思路-朴素双指针) 4 | 5 | ### 思路 朴素双指针 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var reverseWords = function(s) { 11 | s = s.split(' ').filter((e) => e !== '') 12 | let l = 0, r = s.length - 1 13 | 14 | while(l < r){ 15 | let temp = s[l] 16 | 17 | s[l] = s[r] 18 | s[r] = temp 19 | l++ 20 | r-- 21 | } 22 | 23 | 24 | return s.join(' ') 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 时间复杂度:
31 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC156. Binary Tree Upside Down.md: -------------------------------------------------------------------------------- 1 | ## LC 156. Binary Tree Upside Down 2 | https://leetcode-cn.com/problems/binary-tree-upside-down/ 3 | ### 思路 解法副标题 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var upsideDownBinaryTree = function(root) { 9 | let right = parent = null; 10 | let node = root 11 | 12 | while(node){ 13 | let left = node.left 14 | node.left = right 15 | right = node.right 16 | node.right = parent 17 | parent = node 18 | node = left 19 | } 20 | return parent 21 | }; 22 | 23 | ``` 24 | 25 | #### 复杂度分析 26 | 时间复杂度:
27 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC159. Longest Substring with At Most Two Distinct Characters.md: -------------------------------------------------------------------------------- 1 | ## LC 159. Longest Substring with At Most Two Distinct Characters 2 | https://leetcode-cn.com/problems/longest-substring-with-at-most-two-distinct-characters/ 3 | - [哈希表滑动窗口](#思路-哈希表滑动窗口) 4 | 5 | ### 思路 哈希表滑动窗口 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var lengthOfLongestSubstringTwoDistinct = function(s) { 11 | if(s.length <= 2) return s.length 12 | let m = new Map 13 | let l = 0; 14 | let ans = 0; 15 | for(let r = 0; r < s.length; r++){ 16 | const c = s[r] 17 | m.set(c, (m.get(c) || 0 )+ 1) 18 | while(m.size > 2 && l <= r){ 19 | m.set(s[l], m.get(s[l]) -1) 20 | if(m.get(s[l]) === 0) m.delete(s[l]) 21 | l++ 22 | } 23 | 24 | ans = Math.max(ans, r - l + 1) 25 | 26 | } 27 | 28 | return ans 29 | }; 30 | 31 | ``` 32 | 33 | #### 复杂度分析 34 | 时间复杂度:
35 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC161. One Edit Distance.md: -------------------------------------------------------------------------------- 1 | ## LC 161. One Edit Distance 2 | 3 | - [双指针分类讨论](#思路-双指针分类讨论) 4 | 5 | ### 思路 双指针分类讨论 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var isOneEditDistance = function(s, t) { 11 | if(s.length > t.length){ 12 | let temp = s 13 | s = t 14 | t = temp 15 | } 16 | 17 | if(t.length - s.length > 1) return false 18 | 19 | //s short 20 | 21 | for(let i = 0; i < s.length; i++){ 22 | if(s[i] !== t[i]){ 23 | //aec abc 24 | if(s.length === t.length) return s.slice(i + 1) === t.slice(i + 1) 25 | //abc aebc 26 | else return s.slice(i) === t.slice(i + 1) 27 | } 28 | } 29 | 30 | //abc abcd 31 | 32 | return s.length +1 === t.length 33 | }; 34 | 35 | ``` 36 | 37 | #### 复杂度分析 38 | 时间复杂度:
39 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC167. Two Sum II - Input array is sorted.md: -------------------------------------------------------------------------------- 1 | ## LC 167. Two Sum II - Input array is sorted 2 | 3 | - [哈希表](#思路-哈希表) 4 | 5 | ### 思路 哈希表 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var twoSum = function(numbers, target) { 11 | const m = new Map 12 | 13 | for(let i = 0; i < numbers.length; i++){ 14 | let n = numbers[i] 15 | if(m.has(target- n)) return [m.get(target - n), i + 1] 16 | 17 | m.set(n, i + 1) 18 | } 19 | }; 20 | 21 | ``` 22 | 23 | #### 复杂度分析 24 | 时间复杂度:
25 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC168. Excel Sheet Column Title.md: -------------------------------------------------------------------------------- 1 | ## LC 168. Excel Sheet Column Title 2 | 3 | - [数学](#思路-数学) 4 | 171逆推过来的 5 | ### 思路 数学 6 | 7 | 本题是 10 进制转换 26 进制 8 | 9 | 10 进制转换 N 进制的方法是,除 N 取余,整数倒序输出余数,小数正序输出余数。 10 | 11 | 但是本题 A 对应的余数不是 0, 是 1 12 | Z 对应的余数是 25,不是 0 13 | 14 | N N % 26 (N--)%26 15 | 1 1 0 A 16 | 26 0 25 Z 17 | 18 | 所以调整到 ASCII CODE A (65) 19 | 20 | #### 代码 JavaScript 21 | 22 | ```JavaScript 23 | var convertToTitle = function(columnNumber) { 24 | let res = '' 25 | //ASCII code 65 A 1 26 | 27 | while(columnNumber > 0){ 28 | columnNumber-- 29 | let remain = columnNumber % 26 30 | columnNumber = Math.floor(columnNumber / 26) 31 | 32 | res = String.fromCharCode(65 + remain) + res 33 | } 34 | 35 | return res; 36 | }; 37 | 38 | ``` 39 | 40 | #### 复杂度分析 41 | 42 | 时间复杂度:O(N)
43 | 空间复杂度:O(1) 44 | -------------------------------------------------------------------------------- /Basic200II/LC171. Excel Sheet Column Number.md: -------------------------------------------------------------------------------- 1 | ## LC 171. Excel Sheet Column Number 2 | 3 | 4 | #### 代码 JavaScript 5 | 6 | ```JavaScript 7 | 8 | var titleToNumber = function(columnTitle) { 9 | 10 | let number = 0 11 | for(const t of columnTitle){ 12 | const k = t.charCodeAt() - 65 + 1 13 | number = number * 26 + k 14 | } 15 | 16 | return number 17 | }; 18 | ``` 19 | 20 | #### 复杂度分析 21 | 时间复杂度:
22 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC179. Largest Number.md: -------------------------------------------------------------------------------- 1 | ## LC 179. Largest Number 2 | https://leetcode-cn.com/problems/largest-number/ 3 | 类似的https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/ 4 | ### 思路 贪心 5 | review 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var largestNumber = function(nums) { 10 | nums.sort((x,y) => { 11 | let sx = 10, sy = 10; 12 | 13 | while(sx <= x) sx *= 10 14 | while(sy <= y) sy *= 10 15 | console.log(x,y, 'sx', sx, 'sy', sy, 'first',(sx * y + x).toString(), 'second', (sy * x + y).toString()) 16 | return (sx * y + x).toString() - (sy * x + y).toString() 17 | }) 18 | 19 | if(nums[0] === 0) return '0'; 20 | 21 | return nums.join('') 22 | }; 23 | 24 | ``` 25 | 26 | #### 复杂度分析 27 | 时间复杂度:
28 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC186. Reverse Words in a String II.md: -------------------------------------------------------------------------------- 1 | ## LC 186. Reverse Words in a String II 2 | 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var reverseWords = function(s) { 11 | s = s.reverse() 12 | let slow = 0 13 | for(let fast = 0; fast < s.length; fast++){ 14 | if(s[fast] === ' ' || fast == (s.length - 1)){ 15 | let l = slow, r = fast == (s.length - 1) ? fast : fast - 1 16 | while(l < r){ 17 | [s[l], s[r]] = [s[r], s[l]] 18 | l++ 19 | r-- 20 | } 21 | slow = fast + 1 22 | } 23 | } 24 | }; 25 | 26 | ``` 27 | 28 | #### 复杂度分析 29 | 时间复杂度:
30 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC187. Repeated DNA Sequences.md: -------------------------------------------------------------------------------- 1 | ## LC 187. Repeated DNA Sequences 2 | 3 | 4 | ### 思路 解法副标题 5 | 需要显示是否被push过 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var findRepeatedDnaSequences = function(s) { 10 | const dic = new Map() 11 | const ret = [] 12 | for(let i = 0; i <= s.length - 10; i++){ 13 | const cur = s.slice(i, i + 10) 14 | if(dic.has(cur)){ 15 | if(dic.get(cur))ret.push(cur) 16 | dic.set(cur, false) 17 | } 18 | else dic.set(cur, true) 19 | } 20 | 21 | return ret 22 | }; 23 | 24 | ``` 25 | 26 | #### 复杂度分析 27 | 时间复杂度:
28 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC19. Remove Nth Node From End of List.md: -------------------------------------------------------------------------------- 1 | ## LC 19. Remove Nth Node From End of List 2 | https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/ 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 两个指针,一个是队尾(null),另一个是被移除之前的点; 7 | 主要难点在于要数对关系 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var removeNthFromEnd = function(head, n) { 12 | if(!head) return null 13 | const dummy = new ListNode(-1,head) 14 | 15 | let pre = dummy, cur = head; 16 | let k = n 17 | while(k-- > 0){ 18 | cur = cur.next 19 | if(cur == null) break 20 | } 21 | 22 | while(cur){ 23 | cur = cur.next 24 | pre = pre.next 25 | } 26 | 27 | const next = pre.next.next 28 | pre.next = next 29 | 30 | return dummy.next 31 | 32 | }; 33 | 34 | ``` 35 | 36 | #### 复杂度分析 37 | 时间复杂度:O(N)
38 | 空间复杂度:O(1) 39 | -------------------------------------------------------------------------------- /Basic200II/LC199. Binary Tree Right Side View.md: -------------------------------------------------------------------------------- 1 | ## LC 199. Binary Tree Right Side View 2 | 3 | - [二叉树遍历](#思路-二叉树遍历) 4 | 5 | ### 思路 二叉树遍历 6 | 7 | 二叉树遍历 BFS 带层 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var rightSideView = function(root) { 13 | if(!root) return []; 14 | const res = []; 15 | const queue = [root] 16 | while(queue.length){ 17 | const levelSize = queue.length; 18 | for(let i =0; i < levelSize; i++){ 19 | const node = queue.shift() 20 | if(i === levelSize - 1) res.push(node.val) 21 | node.left && queue.push(node.left) 22 | node.right && queue.push(node.right) 23 | } 24 | } 25 | 26 | return res; 27 | }; 28 | 29 | ``` 30 | 31 | #### 复杂度分析 32 | 33 | 时间复杂度:O(N)
34 | 空间复杂度:O(N) the size of queue 35 | -------------------------------------------------------------------------------- /Basic200II/LC20. Valid Parentheses.md: -------------------------------------------------------------------------------- 1 | ## LC 20. Valid Parentheses 2 | https://leetcode-cn.com/problems/valid-parentheses/ 3 | - [辅助栈](#思路-辅助栈) 4 | 5 | ### 思路 辅助栈 6 | 利用栈FILO的特性 7 | 注意可能有edge case '[' 所以不仅要检查是否配对,还要检查是否有残留 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | 12 | var isValid = function(s) { 13 | const memo = new Map([ 14 | ['(', ')'], 15 | ['[', ']'], 16 | ['{', '}'] 17 | ]); 18 | const stack = [] 19 | 20 | for(const c of s){ 21 | if(memo.has(c)){ 22 | stack.push(memo.get(c)) 23 | }else{ 24 | const t = stack.pop() 25 | if(t != c) return false 26 | } 27 | } 28 | 29 | return stack.length == 0 30 | } 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 时间复杂度:O(N)
36 | 空间复杂度:O(1) 37 | -------------------------------------------------------------------------------- /Basic200II/LC202. Happy Number.md: -------------------------------------------------------------------------------- 1 | ## LC 202. Happy Number 2 | https://leetcode-cn.com/problems/happy-number/ 3 | 4 | 5 | ### 思路 有环 6 | 因为有了1之后,就会一直稳定在一,所以如果fast === slow,检测fast是不是等于1就可以了。 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var isHappy = function(n) { 11 | 12 | //if circle, no 13 | // if one, yes 14 | let slow = getNext(n), fast = getNext(slow) 15 | while(fast !== slow){ 16 | if(slow === 1) return true 17 | slow = getNext(slow) 18 | fast = getNext(getNext(fast)) 19 | // console.log(slow, fast) 20 | } 21 | 22 | return fast === 1 23 | 24 | }; 25 | 26 | const getNext = (n) => { 27 | let res = 0 28 | while(n > 0){ 29 | let target = n % 10 30 | n = Math.floor(n / 10) 31 | res += target ** 2 32 | } 33 | return res 34 | } 35 | 36 | ``` 37 | 38 | #### 复杂度分析 39 | 时间复杂度:
40 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC206. Reverse Linked List.md: -------------------------------------------------------------------------------- 1 | ## LC 206. Reverse Linked List 2 | https://leetcode-cn.com/problems/reverse-linked-list/ 3 | - [BFS](#思路-BFS) 4 | 5 | ### 思路 BFS 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var reverseList = function(head) { 11 | let pre = null 12 | while(head){ 13 | const next = head.next 14 | 15 | head.next = pre 16 | 17 | pre = head 18 | head = next 19 | } 20 | return pre 21 | }; 22 | 23 | ``` 24 | 25 | #### 复杂度分析 26 | 时间复杂度:
27 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC21. Merge Two Sorted Lists.md: -------------------------------------------------------------------------------- 1 | ## LC 21. Merge Two Sorted Lists 2 | 3 | - [迭代](#思路-迭代) 4 | 5 | ### 思路 迭代 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var mergeTwoLists = function(l1, l2) { 11 | const dummyHead = new ListNode(0) 12 | let cur = dummyHead 13 | while(l1 && l2){ 14 | if(l1.val > l2.val){ 15 | cur.next = l2 16 | l2 = l2.next 17 | }else{ 18 | cur.next = l1 19 | l1 = l1.next 20 | } 21 | cur = cur.next 22 | } 23 | 24 | if(l1) cur.next = l1 25 | if(l2) cur.next = l2 26 | 27 | return dummyHead.next 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 时间复杂度:O(N)
34 | 空间复杂度:O(1) 35 | -------------------------------------------------------------------------------- /Basic200II/LC214. Shortest Palindrome.md: -------------------------------------------------------------------------------- 1 | ## LC 214. Shortest Palindrome 2 | 3 | - [暴力](#思路-暴力) 4 | review 5 | ### 思路 暴力 6 | "banana" + "ananab"肯定是回文串 7 | 然后从中寻找最短的,当 s.slice(x)=== rev.slice(x)的时候就是了 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var shortestPalindrome = function(s) { 12 | let rev = s.split('').reverse().join('') 13 | 14 | 15 | 16 | for(let i = s.length; i >= 0; i--){ 17 | console.log(s.slice(0,i), rev.slice(s.length - i)) 18 | if(s.slice(0,i) === rev.slice(s.length - i)){ 19 | return rev.slice(0, s.length - i) + s 20 | } 21 | } 22 | }; 23 | 24 | ``` 25 | 26 | #### 复杂度分析 27 | 时间复杂度:O(n^2)
28 | 空间复杂度:O(1) -------------------------------------------------------------------------------- /Basic200II/LC216. Combination Sum III.md: -------------------------------------------------------------------------------- 1 | ## LC 216. Combination Sum III 2 | https://leetcode-cn.com/problems/combination-sum-iii/ 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var combinationSum3 = function(k, n) { 11 | const ret = [] 12 | 13 | const bt = (cur, remainN, startIndex)=>{ 14 | if(remainN <= 0 || cur.length >= k){ 15 | if(cur.length === k && remainN === 0){ 16 | ret.push(cur.slice()) 17 | } 18 | return 19 | } 20 | 21 | for(let i = startIndex; i <= 9; i++){ 22 | bt(cur.concat(i), remainN - i, i + 1) 23 | } 24 | } 25 | 26 | bt([], n, 1) 27 | 28 | return ret 29 | }; 30 | 31 | ``` 32 | 33 | #### 复杂度分析 34 | 时间复杂度:
35 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC219. Contains Duplicate II.md: -------------------------------------------------------------------------------- 1 | ## LC 219. Contains Duplicate II 2 | https://leetcode-cn.com/problems/contains-duplicate-ii/ 3 | - [滑动窗口](#思路-滑动窗口) 4 | 5 | ### 思路 滑动窗口 6 | 维护大小为k的滑动窗口,坑是nums.length < k 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var containsNearbyDuplicate = function(nums, k) { 11 | const len = Math.min(nums.length, k) 12 | const m = new Set 13 | 14 | for(let i = 0; i <= len; i++){ 15 | if(m.has(nums[i]))return true 16 | else m.add(nums[i]) 17 | } 18 | 19 | 20 | 21 | for(let i = k + 1, j = 0; i < nums.length; i++, j++){ 22 | m.delete(nums[j]) 23 | 24 | if(m.has(nums[i])) return true 25 | else m.add(nums[i]) 26 | 27 | } 28 | 29 | return false 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 时间复杂度:
36 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC22. Generate Parentheses.md: -------------------------------------------------------------------------------- 1 | ## LC 22. Generate Parentheses 2 | 3 | - [回溯](#思路-回溯) 4 | 5 | ### 思路 回溯 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var generateParenthesis = function(n) { 11 | const res = [] 12 | var dfs = function(cur, left, right){ 13 | // console.log(cur, left, right) 14 | if(right > left || left > n || right > n) return; 15 | 16 | if(left == n && right == n){ 17 | res.push(cur) 18 | return 19 | } 20 | 21 | dfs(cur + '(', left + 1, right) 22 | dfs(cur + ')', left, right+1) 23 | } 24 | 25 | dfs('(',1,0) 26 | return res 27 | }; 28 | 29 | ``` 30 | 31 | #### 复杂度分析 32 | 时间复杂度:
33 | 空间复杂度: 34 | -------------------------------------------------------------------------------- /Basic200II/LC221. Maximal Square.md: -------------------------------------------------------------------------------- 1 | ## LC 221. Maximal Square 2 | 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | f[i][j]是以该点为右下角的最大正方形连续变长 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var maximalSquare = function(matrix) { 11 | const row = matrix.length, col = matrix[0].length; 12 | let maxSide = 0 13 | const f = Array.from({length: row}).map(() => Array.from({length: col}).fill(0)) 14 | 15 | for(let i = 0; i < row; i++){ 16 | for(let j = 0; j < col; j++){ 17 | if(matrix[i][j] == '1'){ 18 | if(i == 0 || j == 0) f[i][j] = 1 19 | else f[i][j] = Math.min(f[i - 1][j], f[i][j - 1], f[i - 1][j - 1]) + 1 20 | } 21 | maxSide = Math.max(maxSide, f[i][j]) 22 | } 23 | } 24 | 25 | return maxSide ** 2 26 | }; 27 | 28 | ``` 29 | 30 | #### 复杂度分析 31 | 时间复杂度:
32 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC222. Count Complete Tree Nodes.md: -------------------------------------------------------------------------------- 1 | ## LC 222. Count Complete Tree Nodes 2 | https://leetcode-cn.com/problems/count-complete-tree-nodes/ 3 | - [递归](#思路-递归) 4 | ### 思路 递归 5 | TODO shorter one 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var countNodes = function(root) { 11 | if(!root) return 0 12 | 13 | return countNodes(root.left) + countNodes(root.right)+ 1 14 | }; 15 | 16 | ``` 17 | 18 | #### 复杂度分析 19 | 时间复杂度:
20 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC230. Kth Smallest Element in a BST.md: -------------------------------------------------------------------------------- 1 | ## LC 230. Kth Smallest Element in a BST 2 | 3 | - [中序遍历](#思路-中序遍历) 4 | 5 | ### 思路 中序遍历 6 | 考察中序遍历的迭代 7 | 这里的res可以改成数字,而不是数组。while的停止条件就是k > 0 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var kthSmallest = function(root, k) { 12 | const res = [] 13 | const stack = [] 14 | 15 | const firstStep = (node) => { 16 | while(node){ 17 | stack.push(node) 18 | node = node.left 19 | } 20 | } 21 | 22 | firstStep(root) 23 | 24 | while(res.length < k){ 25 | let node = stack.pop() 26 | res.push(node.val) 27 | node = node.right 28 | firstStep(node) 29 | } 30 | 31 | return res[res.length - 1] 32 | }; 33 | 34 | ``` 35 | 36 | #### 复杂度分析 37 | 时间复杂度:O(H + k) 当是平衡树的时候 H = logN
38 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC236. Lowest Common Ancestor of a Binary Tree.md: -------------------------------------------------------------------------------- 1 | ## LC 236. Lowest Common Ancestor of a Binary Tree 2 | 3 | - [DFS](#思路-DFS) 4 | 5 | ### 思路 DFS 6 | 我们只关心这个树里有没有p和q; 7 | 如果遇到`!root`就返回`null`;如果遇到`p || q`就返回root(p或者q)。 8 | 利用value unique 9 | 这样的话,p 和 q只有三种情况: 10 | 1. 左右都有返回,那么也就是说root是他们的LCA 11 | 2. 左有返回,右没有,那么说明在左子树; 12 | 3. 右有返回,左没有,那么说明在右子树; 13 | 14 | 为什么是递归呢: 15 | 因为p和q有两种情况,如果pq分在root左右侧,那么LCA是root; 16 | 如果p和q在某一侧子树中,那么这个问题可以变成同样的、规模更小的问题。 17 | #### 代码 JavaScript 18 | 19 | ```JavaScript 20 | var lowestCommonAncestor = function(root, p, q) { 21 | if(!root) return null 22 | 23 | if(root == q || root == p) return root 24 | 25 | const left = lowestCommonAncestor(root.left, p, q) 26 | const right = lowestCommonAncestor(root.right, p, q) 27 | 28 | if(left && right) return root 29 | 30 | if(!left) return right 31 | else return left 32 | }; 33 | 34 | ``` 35 | 36 | #### 复杂度分析 37 | 时间复杂度:
38 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC237. Delete Node in a Linked List.md: -------------------------------------------------------------------------------- 1 | ## LC 237. Delete Node in a Linked List 2 | 3 | https://leetcode-cn.com/problems/delete-node-in-a-linked-list/ 4 | 5 | ### 思路 6 | 需要前一个节点来删除现在的节点,所以我们可以拷贝下一个节点的值,然后删除下一个节点。 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var deleteNode = function(node) { 11 | node.val = node.next.val 12 | node.next = node.next.next 13 | }; 14 | 15 | ``` 16 | 17 | #### 复杂度分析 18 | 时间复杂度:
19 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC254. Factor Combinations.md: -------------------------------------------------------------------------------- 1 | ## LC 254. Factor Combinations 2 | 3 | - [回溯](#思路-回溯) 4 | 5 | ### 思路 回溯 6 | 倒着效果更好,节约 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var getFactors = function(n) { 11 | const ret = [] 12 | if(n === 1) return ret; 13 | const bt = (cur, remain, curNum) => { 14 | if(remain <= 1){ 15 | if(remain == 1){ 16 | ret.push(cur.slice()) 17 | } 18 | return; 19 | } 20 | 21 | for(let i = curNum; i > 1; i--){ 22 | if(remain % i === 0){ 23 | bt(cur.concat(i), remain / i, i) 24 | } 25 | } 26 | } 27 | 28 | bt([], n, n - 1) 29 | return ret 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 时间复杂度:
36 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC259. 3Sum Smaller.md: -------------------------------------------------------------------------------- 1 | ## LC 259. 3Sum Smaller 2 | https://leetcode-cn.com/problems/3sum-smaller/ 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 有序数组拍扁之后是可以完全遍历数组的。 7 | 在`nums[i] + nums[j] < curTarget`的时候就是要统计的对数 8 | 比如[-2,0,1,3,5] k = 4, j = 3, i = 0 的时候,统计了有i的个数,然后i++,继续统计。 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var threeSumSmaller = function(nums, target) { 13 | nums.sort((a,b) => a - b) 14 | 15 | // -2 0 1 3 16 | // i + j < target - k 17 | let ret = 0 18 | for(let k = 2; k < nums.length; k++){ 19 | const curTarget = target - nums[k] 20 | 21 | let i = 0; j = k - 1 22 | 23 | while(i < j){ 24 | if(nums[i] + nums[j] >= curTarget)j-- 25 | else { 26 | ret += j - i 27 | i++ 28 | } 29 | } 30 | } 31 | 32 | return ret 33 | }; 34 | 35 | ``` 36 | 37 | #### 复杂度分析 38 | 时间复杂度:O(n^2)
39 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC27. Remove Element.md: -------------------------------------------------------------------------------- 1 | ## LC 27. Remove Element 2 | 3 | 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var removeElement = function(nums, val) { 9 | let slow = 0 10 | for(let fast = 0; fast < nums.length; fast++){ 11 | if(nums[fast] != val){ 12 | nums[slow] = nums[fast] 13 | slow++ 14 | } 15 | } 16 | 17 | return slow 18 | 19 | }; 20 | 21 | ``` 22 | 23 | 24 | 25 | ### 思路 双指针 26 | 27 | #### 代码 JavaScript 28 | 29 | ```JavaScript 30 | var removeElement = function(nums, val) { 31 | let j = nums.length - 1, i = 0 32 | 33 | while(i <= j){ 34 | if(nums[i] == val){ 35 | nums[i] = nums[j] 36 | j-- 37 | }else{ 38 | i++ 39 | } 40 | } 41 | 42 | return i 43 | 44 | 45 | }; 46 | 47 | ``` 48 | 49 | #### 复杂度分析 50 | 时间复杂度:
51 | 空间复杂度: 52 | 53 | https://leetcode-cn.com/problems/remove-element/solution/shua-chuan-lc-shuang-bai-shuang-zhi-zhen-mzt8/ -------------------------------------------------------------------------------- /Basic200II/LC274. H-Index.md: -------------------------------------------------------------------------------- 1 | ## LC 274. H-Index 2 | https://leetcode-cn.com/problems/h-index/ 3 | 4 | ### 思路 二分 能力检测 5 | 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var hIndex = function(citations) { 10 | // console.log(check(citations, 3)) 11 | 12 | let l = 0, r = citations.length 13 | while(l <= r){ 14 | const mid = l + ((r - l) >> 1) 15 | if(check(citations, mid)){ 16 | l = mid + 1 17 | }else{ 18 | r = mid - 1 19 | } 20 | } 21 | 22 | return r 23 | }; 24 | 25 | const check = (citations, mid) => { 26 | let atleastH = 0 27 | 28 | for(const c of citations){ 29 | if(c >= mid) atleastH++ 30 | } 31 | 32 | return atleastH >= mid 33 | } 34 | 35 | ``` 36 | 37 | #### 复杂度分析 38 | 时间复杂度:
39 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC277. Find the Celebrity.md: -------------------------------------------------------------------------------- 1 | ## LC 277. Find the Celebrity 2 | 3 | - [根据题意双指针](#思路-根据题意双指针) 4 | 5 | ### 思路 根据题意双指针 6 | 双指针因为答案有二分性 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var solution = function(knows) { 11 | /** 12 | * @param {integer} n Total people 13 | * @return {integer} The celebrity 14 | */ 15 | return function(n) { 16 | // for(let i = 1; i < n; i++){ 17 | // knows(r, i) && (r = i) 18 | // } 19 | // for(let i = 0; i < n; i++) 20 | // if(i < r && knows(r, i) || i !== r && !knows(i,r)) return -1 21 | // return r 22 | let l = 0, r = n - 1 23 | while(l != r ){ 24 | knows(l, r) ? l++ : r -- 25 | } 26 | for(let i = 0; i < n;i++){ 27 | if(i !== l && (knows(l, i) || !knows(i, l))) return -1 28 | } 29 | return l; 30 | 31 | }; 32 | }; 33 | 34 | ``` 35 | 36 | #### 复杂度分析 37 | 时间复杂度:O(n)
38 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC283. Move Zeroes.md: -------------------------------------------------------------------------------- 1 | ## LC 283. Move Zeroes 2 | https://leetcode-cn.com/problems/move-zeroes/ 3 | ### 思路 双指针 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var moveZeroes = function(nums) { 9 | let p1 = 0 10 | for(let i = 0; i < nums.length; i++){ 11 | if(nums[i] !== 0){ 12 | nums[p1] = nums[i] 13 | p1++ 14 | } 15 | } 16 | while(p1 < nums.length){ 17 | nums[p1] = 0 18 | p1++ 19 | } 20 | }; 21 | 22 | ``` 23 | 24 | #### 复杂度分析 25 | 时间复杂度:
26 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC287. Find the Duplicate Number.md: -------------------------------------------------------------------------------- 1 | ## LC 287. Find the Duplicate Number 2 | https://leetcode-cn.com/problems/find-the-duplicate-number/ 3 | 4 | ### 思路 floyds 5 | 链表和数组经常能看成环 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var findDuplicate = function(nums) { 10 | let slow = 0, fast = 0 11 | do{ 12 | slow = nums[slow] 13 | fast = nums[nums[fast]] 14 | } while(slow != fast) 15 | 16 | slow = 0 17 | while(slow != fast){ 18 | slow = nums[slow] 19 | fast = nums[fast] 20 | } 21 | 22 | return slow 23 | 24 | 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 时间复杂度:
31 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC29. Divide Two Integers.md: -------------------------------------------------------------------------------- 1 | ## LC 29. Divide Two Integers 2 | https://leetcode-cn.com/problems/divide-two-integers/ 3 | 4 | ### 思路 5 | 注意读题和边界条件,注意当都是负数的时候其实是正数。 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var divide = function(dividend, divisor) { 10 | let neg = false 11 | if(dividend < 0 || divisor < 0) neg= true 12 | if(divisor < 0 && dividend < 0) neg = false 13 | let ans = 0 14 | if(neg){ 15 | ans = Math.ceil(dividend / divisor) 16 | }else{ 17 | ans = Math.floor(dividend / divisor) 18 | } 19 | 20 | // if() ans = (-2) ** 31 21 | if(ans < (-2) ** 31 || ans > 2 **31 - 1) ans = (2 ** 31) - 1 22 | return ans 23 | }; 24 | 25 | ``` 26 | 27 | #### 复杂度分析 28 | 时间复杂度:
29 | 空间复杂度: 30 | -------------------------------------------------------------------------------- /Basic200II/LC347. Top K Frequent Elements.md: -------------------------------------------------------------------------------- 1 | ## LC 347. Top K Frequent Elements 2 | https://leetcode-cn.com/problems/top-k-frequent-elements/ 3 | - [heap小顶堆](#思路-heap小顶堆) 4 | 5 | ### 思路 heap小顶堆 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var topKFrequent = function(nums, k) { 11 | if(k === 0) return [] 12 | const mh = new MinPriorityQueue() 13 | const memo = new Map 14 | for(const n of nums){ 15 | memo.set(n, (memo.get(n) || 0) + 1) 16 | } 17 | 18 | for(const n of new Set(nums)){ 19 | if(mh.size() < k){ 20 | mh.enqueue(n,memo.get(n)) 21 | }else{ 22 | if(memo.get(n) > mh.front()['priority']){ 23 | mh.dequeue() 24 | mh.enqueue(n,memo.get(n)) 25 | } 26 | } 27 | } 28 | 29 | const res = [] 30 | while(!mh.isEmpty()){ 31 | res.push(mh.dequeue()['element']) 32 | } 33 | 34 | return res 35 | }; 36 | 37 | ``` 38 | 39 | #### 复杂度分析 40 | 时间复杂度:nlogk
41 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC352. Data Stream as Disjoint Intervals.md: -------------------------------------------------------------------------------- 1 | ## LC 352. Data Stream as Disjoint Intervals 2 | 3 | - [nb大佬的解法](#思路-nb大佬的解法) 4 | 5 | ### 思路 nb大佬的解法 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var SummaryRanges = function() { 11 | this.all = [] 12 | }; 13 | 14 | /** 15 | * @param {number} val 16 | * @return {void} 17 | */ 18 | SummaryRanges.prototype.addNum = function(val) { 19 | this.all[val] = val 20 | }; 21 | 22 | /** 23 | * @return {number[][]} 24 | */ 25 | SummaryRanges.prototype.getIntervals = function() { 26 | var s = this.all.join(',') // 拼接 27 | console.log('21', s) 28 | var arr = s.match(/(\d,?)+/g) // 将拼接后的连续的数值取出 29 | console.log('23', arr) 30 | var res = arr.map(v => { 31 | var temp = v.split(',').filter(v => v) // 分隔后有的项会有空值,需要去除 32 | console.log('26', temp) 33 | return [temp[0], temp[temp.length - 1]] 34 | }) 35 | return res 36 | 37 | } 38 | 39 | ``` 40 | 41 | #### 复杂度分析 42 | 时间复杂度:
43 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC38. Count and Say.md: -------------------------------------------------------------------------------- 1 | ## LC 38. Count and Say 2 | https://leetcode-cn.com/problems/count-and-say/ 3 | 4 | ### 思路 模拟 5 | 注意可以添加哨兵简化最后的判断 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var countAndSay = function(n) { 10 | let res = '1' 11 | if(n == 1) return res 12 | 13 | for(let i = 2; i <= n; i++){ 14 | res = nextString(res) 15 | } 16 | return res 17 | 18 | }; 19 | 20 | var nextString = function(s){ 21 | s += '&' 22 | let cur = s[0] 23 | let curCount = 1 24 | let res = '' 25 | for(let i = 1; i 43 | 空间复杂度:O(N) 44 | -------------------------------------------------------------------------------- /Basic200II/LC387. First Unique Character in a String.md: -------------------------------------------------------------------------------- 1 | ## LC 387. First Unique Character in a String 2 | https://leetcode-cn.com/problems/first-unique-character-in-a-string/ 3 | - [哈希表](#思路-哈希表) 4 | 5 | ### 思路 哈希表 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var firstUniqChar = function(s) { 11 | const memo = new Map 12 | for(const c of s){ 13 | memo.set(c, (memo.get(c) || 0) + 1) 14 | } 15 | let char = '' 16 | for(let [k, v] of memo.entries()){ 17 | // console.log(k,v) 18 | if(v === 1){ 19 | char = k 20 | break; 21 | } 22 | } 23 | 24 | if(char !== ''){ 25 | return s.indexOf(char) 26 | }else return -1 27 | }; 28 | 29 | ``` 30 | 31 | #### 复杂度分析 32 | 时间复杂度:
33 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC39. Combination Sum.md: -------------------------------------------------------------------------------- 1 | ## LC 39. Combination Sum 2 | 3 | - [标准回溯](#思路-标准回溯) 4 | 5 | ### 思路 标准回溯 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var combinationSum = function(candidates, target) { 11 | const res = [] 12 | 13 | const bt = (tempList, remain, startIndex) => { 14 | if(remain == 0){ 15 | res.push(tempList.slice()) 16 | return 17 | } 18 | if(remain < 0){ 19 | return 20 | } 21 | 22 | for(let i = startIndex; i < candidates.length; i++){ 23 | tempList.push(candidates[i]) 24 | bt(tempList, remain - candidates[i], i) 25 | tempList.pop() 26 | } 27 | } 28 | bt([], target, 0) 29 | return res 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 时间复杂度:所有可行解的长度之和
36 | 空间复杂度:target层 37 | -------------------------------------------------------------------------------- /Basic200II/LC424. Longest Repeating Character Replacement.md: -------------------------------------------------------------------------------- 1 | ## LC 424. Longest Repeating Character Replacement 2 | https://leetcode-cn.com/problems/longest-repeating-character-replacement/ 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 窗口内最多修改`k`个字符 = `窗口大小 - 最多的字符个数` 7 | 所以不需要枚举窗口,只要找到一个最大就可以了 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | 12 | var characterReplacement = function(s, k) { 13 | const memo = new Array(26).fill(0) 14 | let maxn = 0 15 | let l = 0, r = 0 16 | while(r < s.length){ 17 | const c = s[r].charCodeAt() - 65 18 | memo[c]++ 19 | maxn = Math.max(maxn, memo[c]) 20 | if(r - l + 1 - maxn > k){ 21 | const lc = s[l].charCodeAt() - 65 22 | memo[lc]-- 23 | l++ 24 | } 25 | 26 | r++ 27 | 28 | } 29 | 30 | return r - l 31 | }; 32 | ``` 33 | 34 | #### 复杂度分析 35 | 时间复杂度:O(n)
36 | 空间复杂度:O(1) -------------------------------------------------------------------------------- /Basic200II/LC45. Jump Game II.md: -------------------------------------------------------------------------------- 1 | ## LC 45. Jump Game II 2 | 3 | - [贪心](#思路-贪心) 4 | 5 | ### 思路 贪心 6 | 有点像事后诸葛亮 7 | 维持一个furthest,是最远可以达到的距离 8 | 维持一个end,是当前步数可以达到的距离。每次走到尽头发现还没走到,就假装自己选择在furthest的那个点再迈一步。step++ 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var jump = function(nums) { 13 | let furthest = 0 14 | let cur = 0 15 | let end = 0 16 | let step = 0 17 | while(cur < nums.length - 1){ 18 | furthest = Math.max(furthest, cur + nums[cur]) 19 | if(cur == end){ 20 | end = furthest 21 | step++ 22 | } 23 | cur++ 24 | } 25 | 26 | return step 27 | }; 28 | 29 | ``` 30 | 31 | #### 复杂度分析 32 | 时间复杂度:O(N)
33 | 空间复杂度:O(1) 34 | -------------------------------------------------------------------------------- /Basic200II/LC456. 132 Pattern.md: -------------------------------------------------------------------------------- 1 | ## LC 456. 132 Pattern 2 | https://leetcode-cn.com/problems/132-pattern/ 3 | - [单调栈](#思路-单调栈) 4 | 5 | ### 思路 单调栈 6 | https://leetcode-cn.com/problems/132-pattern/solution/xiang-xin-ke-xue-xi-lie-xiang-jie-wei-he-95gt/ 7 | 分析枚举ijk,发现倒序遍历维护递减单调栈。 8 | 如果有k,那么k必然是由单调栈pop得来的。单调栈内必然有数字,因为只有nums[i] > 单调栈尾才会触发pop。 9 | 10 | 如果这时候前面有个i小于k,那么必然满足这个关系。 11 | #### 代码 JavaScript 12 | 13 | ```JavaScript 14 | 15 | var find132pattern = function(nums) { 16 | const stack = [] 17 | let k = Number.MIN_SAFE_INTEGER 18 | for(let i = nums.length - 1; i >= 0; i--){ 19 | if(nums[i] < k) return true 20 | while(stack.length && stack[stack.length - 1] < nums[i]){ 21 | k = Math.max(k, stack.pop()) 22 | } 23 | stack.push(nums[i]) 24 | } 25 | 26 | return false 27 | }; 28 | ``` 29 | 30 | #### 复杂度分析 31 | 时间复杂度:O(n)
32 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC55. Jump Game.md: -------------------------------------------------------------------------------- 1 | ## LC 55. Jump Game 2 | 3 | 4 | ### 思路 贪心 5 | 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var canJump = function(nums) { 10 | let fur = 0 11 | let cur = 0 12 | while(cur <= fur && cur < nums.length){ 13 | fur = Math.max(fur, nums[cur] + cur ) 14 | // console.log(cur, fur) 15 | cur++ 16 | } 17 | 18 | return fur >= nums.length - 1 19 | }; 20 | 21 | ``` 22 | 23 | #### 复杂度分析 24 | 时间复杂度:On
25 | 空间复杂度:o1 26 | -------------------------------------------------------------------------------- /Basic200II/LC56. Merge Intervals.md: -------------------------------------------------------------------------------- 1 | ## LC 56. Merge Intervals 2 | https://leetcode-cn.com/problems/merge-intervals/ 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var merge = function(intervals) { 11 | // [s,e] 12 | // e1 >= s2, they can be merged 13 | 14 | intervals.sort((a,b)=> a[0] - b[0]) 15 | const res = [] 16 | let temp = intervals[0] 17 | for(let i = 1; i < intervals.length; i++){ 18 | if(intervals[i][0] <= temp[1]){ 19 | let start = temp[0] 20 | let end = Math.max(temp[1], intervals[i][1]) 21 | temp = [start, end] 22 | }else{ 23 | res.push(temp) 24 | temp = intervals[i] 25 | } 26 | 27 | } 28 | res.push(temp) 29 | 30 | return res 31 | }; 32 | ``` 33 | #### 复杂度分析 34 | 时间复杂度:O(NlogN)
35 | 空间复杂度:O(logN)排序用的额外空间 36 | -------------------------------------------------------------------------------- /Basic200II/LC57. Insert Interval.md: -------------------------------------------------------------------------------- 1 | ## LC 57. Insert Interval 2 | https://leetcode-cn.com/problems/insert-interval/ 3 | 4 | ### 思路 解法副标题 5 | 情况分三段,一段是intervals在重叠区域之前,一段是重叠区域,一段是之后。 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var insert = function(intervals, newInterval) { 10 | if(intervals.length == 0) return [newInterval] 11 | const res = [] 12 | let i = 0 13 | while(i < intervals.length && intervals[i][1] < newInterval[0]){ 14 | res.push(intervals[i]) 15 | i++ 16 | } 17 | 18 | while( i < intervals.length && intervals[i][0] <= newInterval[1] ){ 19 | newInterval[0] = Math.min(newInterval[0], intervals[i][0]) 20 | newInterval[1] = Math.max( newInterval[1], intervals[i][1]) 21 | i++ 22 | } 23 | 24 | 25 | res.push(newInterval) 26 | 27 | while(i < intervals.length){ 28 | res.push(intervals[i]) 29 | i++ 30 | } 31 | 32 | return res; 33 | 34 | }; 35 | 36 | ``` 37 | 38 | #### 复杂度分析 39 | 时间复杂度:
40 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC5782. Maximum Alternating Subsequence Sum.md: -------------------------------------------------------------------------------- 1 | ## LC 5782. Maximum Alternating Subsequence Sum 2 | https://leetcode-cn.com/problems/maximum-alternating-subsequence-sum/ 3 | 4 | ### 思路 动态规划 5 | 推断出可以用两个数组来表示这个动态,在觉得一个数组太复杂的时候。 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var maxAlternatingSum = function(nums) { 10 | const len = nums.length 11 | const even = new Array(len) 12 | const odd = new Array(len) 13 | even[0] = nums[0] 14 | odd[0] = 0 15 | for(let i = 1; i < len; i++){ 16 | odd[i] = Math.max(even[i-1] - nums[i], odd[i -1]) 17 | even[i] = Math.max(odd[i-1] + nums[i], even[i - 1]) 18 | } 19 | 20 | return even[len -1] 21 | }; 22 | 23 | ``` 24 | 25 | #### 复杂度分析 26 | 时间复杂度:
27 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC59. Spiral Matrix II.md: -------------------------------------------------------------------------------- 1 | ## LC 59. Spiral Matrix II 2 | 3 | [模拟](#思路-模拟) 4 | 5 | ### 思路 模拟 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | var generateMatrix = function(n) { 12 | const DIR = [[0,1], [1,0], [0,-1], [-1,0]] 13 | let d = 0 14 | const res = new Array(n).fill(0).map(() => new Array(n).fill(0)) 15 | let count = 0 16 | let i = 0, j = 0 17 | 18 | while(count++ < n * n){ 19 | res[i][j] = count 20 | let ni = i + DIR[d][0] 21 | let nj = j+ DIR[d][1] 22 | if(ni < 0 || nj < 0 || ni >= n || nj >= n || res[ni][nj] != 0){ 23 | d++ 24 | d = d % 4 25 | } 26 | i += DIR[d][0] 27 | j += DIR[d][1] 28 | // console.log(i,j, count) 29 | } 30 | 31 | return res 32 | 33 | }; 34 | ``` 35 | 36 | #### 复杂度分析 37 | 时间复杂度:N^2
38 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC6. ZigZag Conversion.md: -------------------------------------------------------------------------------- 1 | ## LC 6. ZigZag Conversion 2 | 3 | ### 思路 4 | 5 | 注意 numRows == 1 的特殊情况 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var convert = function(s, numRows) { 11 | if(numRows == 1) return s 12 | const ans = new Array(numRows).fill([]) 13 | 14 | let step = -1 15 | let rowIndicator = 0 16 | for(let i = 0; i < s.length; i++){ 17 | if(rowIndicator == 0 || rowIndicator == numRows - 1){ 18 | step = -step 19 | } 20 | 21 | ans[rowIndicator]+= s[i] 22 | rowIndicator += step 23 | } 24 | return ans.join('') 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 31 | 时间复杂度:O(N)
32 | 空间复杂度:O(N) 33 | -------------------------------------------------------------------------------- /Basic200II/LC61. Rotate List.md: -------------------------------------------------------------------------------- 1 | ## LC 61. Rotate List 2 | https://leetcode-cn.com/problems/rotate-list/ 3 | [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var rotateRight = function(head, k) { 11 | if(!head || k == 0) return head 12 | 13 | let len = 1 14 | let cur = head 15 | 16 | while(cur.next){ 17 | cur = cur.next 18 | len++ 19 | } 20 | 21 | ///len = 5 k = 1 , index: len-1 22 | // k = 2 index: len - 2 23 | // k = 3 index: len - 3 24 | // k = 6 index : len - 1 ( 6% 5) 25 | 26 | k = len - k % len 27 | 28 | cur.next = head 29 | while(k > 0){ 30 | cur = cur.next 31 | k-- 32 | } 33 | 34 | const res = cur.next 35 | cur.next = null 36 | 37 | 38 | return res 39 | 40 | 41 | }; 42 | 43 | ``` 44 | 45 | #### 复杂度分析 46 | 时间复杂度:
47 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC66. Plus One.md: -------------------------------------------------------------------------------- 1 | ## LC 66. Plus One 2 | 3 | #### 代码 JavaScript 4 | 5 | ```JavaScript 6 | var plusOne = function(digits) { 7 | let ans = new Array(digits.length).fill(0) 8 | let carry = false 9 | for(let i = digits.length - 1; i >= 0; i--){ 10 | let temp = digits[i] 11 | if(i == digits.length - 1) temp++ 12 | if(carry){ 13 | temp++ 14 | carry = false 15 | } 16 | if(temp >= 10){ 17 | temp = temp % 10 18 | carry = true 19 | } 20 | 21 | 22 | ans[i] = temp 23 | } 24 | // 999 25 | if(carry){ 26 | 27 | ans.unshift(1) 28 | 29 | } 30 | return ans 31 | }; 32 | 33 | ``` 34 | 35 | #### 复杂度分析 36 | 时间复杂度:
37 | 空间复杂度: 38 | -------------------------------------------------------------------------------- /Basic200II/LC69. Sqrt(x).md: -------------------------------------------------------------------------------- 1 | ## LC 69. Sqrt(x) 2 | 3 | https://leetcode-cn.com/problems/sqrtx/ 4 | 5 | - [二分](#思路-二分) 6 | 7 | ### 思路 二分 8 | 9 | 因为得到的答案是最左插入点,所以要么它的平方等于目标数,要么就是在目标数的下一个数(也就是 Math floor) 10 | 比如[1,2,3,4] => 4 11 | 12 | 或者[1,2,3,4,5] => 5 13 | 14 | #### 代码 JavaScript 15 | 16 | ```JavaScript 17 | var mySqrt = function(x) { 18 | let left = 1, right = x 19 | 20 | while(left <= right){ 21 | const mid = left + ((right - left) >> 1) 22 | 23 | if(mid * mid == x){ 24 | right = mid - 1 25 | }else if (mid * mid > x){ 26 | right = mid - 1 27 | }else if( mid * mid < x){ 28 | left = mid + 1 29 | } 30 | } 31 | 32 | return left * left == x ? left : left - 1 33 | }; 34 | 35 | ``` 36 | 37 | #### 复杂度分析 38 | 39 | 时间复杂度:O(logN)
40 | 空间复杂度:O(1) 41 | -------------------------------------------------------------------------------- /Basic200II/LC7. Reverse Integer.md: -------------------------------------------------------------------------------- 1 | ## LC 7. Reverse Integer 2 | 3 | ### 思路 4 | 5 | 注意 Math.floor(1/ 10) = 0 6 | 利用这个特性 7 | 然后记得看条件 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var reverse = function(x) { 13 | if(x == 0) return 0 14 | let negative = false; 15 | if(x < 0){ 16 | negative = true 17 | x = -x 18 | } 19 | 20 | let ans = 0 21 | while(x > 0){ 22 | ans = ans * 10 + x % 10 23 | x = Math.floor(x / 10) 24 | } 25 | 26 | ans = negative ? -ans : ans 27 | return (ans >= (-2) ** 31 && ans <= (2 ** 31 - 1)) ? ans : 0 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 34 | 时间复杂度:O(N) N 等于 number 的长度
35 | 空间复杂度:O(1) 36 | -------------------------------------------------------------------------------- /Basic200II/LC71. Simplify Path.md: -------------------------------------------------------------------------------- 1 | ## LC 71. Simplify Path 2 | 3 | https://leetcode-cn.com/problems/simplify-path/ 4 | ### 思路 5 | 抽象思维又是飞走的一天 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var simplifyPath = function(path) { 10 | const stack = [] 11 | path = path.split('/') 12 | for(let i = 0; i < path.length; i++){ 13 | const c = path[i] 14 | if(stack.length && c == '..') stack.pop() 15 | else if(c != '.' && c != '' && c != '..') stack.push(c) 16 | } 17 | return '/' + stack.join('/') 18 | }; 19 | 20 | ``` 21 | 22 | #### 复杂度分析 23 | 时间复杂度:
24 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC74. Search a 2D Matrix.md: -------------------------------------------------------------------------------- 1 | ## LC 74. Search a 2D Matrix 2 | 3 | ### 思路 解法副标题 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var searchMatrix = function(matrix, target) { 9 | let i = 0, j = matrix[0].length - 1 10 | 11 | while(i < matrix.length && j >= 0){ 12 | const cur = matrix[i][j] 13 | if(cur == target) return true 14 | else if (cur > target) j-- 15 | else if (cur < target) i++ 16 | } 17 | 18 | return false 19 | }; 20 | 21 | ``` 22 | 23 | #### 复杂度分析 24 | 时间复杂度:
25 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC8. String to Integer (atoi).md: -------------------------------------------------------------------------------- 1 | ## LC 8. String to Integer (atoi) 2 | https://leetcode-cn.com/problems/string-to-integer-atoi/ 3 | 4 | ### 思路 string 5 | 注意 + - 只能有一个 所以要用if else if 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | /** 10 | * @param {string} s 11 | * @return {number} 12 | */ 13 | var myAtoi = function(s) { 14 | let ans = 0 15 | let p = 0 16 | let negative = false 17 | 18 | while(s[p] == ' '){p++} 19 | if(s[p]== '-'){ 20 | negative = true 21 | p++ 22 | }else if (s[p] == '+') p++ 23 | 24 | while(s[p] >= '0' && s[p] <= '9'){ 25 | ans = ans * 10 + Number(s[p]) 26 | p++ 27 | } 28 | ans = negative ? ans * -1 : ans 29 | if(ans < (-2)** 31){ 30 | ans = (-2)** 31 31 | }else if(ans > (2**31) - 1){ 32 | ans = (2**31) - 1 33 | } 34 | return ans 35 | 36 | }; 37 | 38 | ``` 39 | 40 | #### 复杂度分析 41 | 时间复杂度:
42 | 空间复杂度: 43 | -------------------------------------------------------------------------------- /Basic200II/LC80. Remove Duplicates from Sorted Array II.md: -------------------------------------------------------------------------------- 1 | ## LC 80. Remove Duplicates from Sorted Array II 2 | 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 7 | 双指针模板 8 | 一个指针 i 进行数组遍历,另外一个指针 j 指向有效数组的最后一个位置。 9 | 10 | 只有当 i 所指向的值和 j 不一致(不重复),才将 i 的值添加到 j 的下一位置。 11 | 12 | slow是等待可能被修改的位置 13 | #### 代码 JavaScript 14 | 15 | ```JavaScript 16 | var removeDuplicates = function(nums) { 17 | 18 | var process = function(nums, k){ 19 | let slow = 0 20 | for(let fast = 0; fast < nums.length; fast++){ 21 | if( slow < k || nums[slow - k] != nums[fast]){ 22 | nums[slow] = nums[fast] 23 | slow++ 24 | } 25 | } 26 | return slow; 27 | } 28 | 29 | return process(nums, 2) 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 36 | 时间复杂度:O(N)
37 | 空间复杂度:O(1) 38 | -------------------------------------------------------------------------------- /Basic200II/LC82. Remove Duplicates from Sorted List II.md: -------------------------------------------------------------------------------- 1 | ## LC 82. Remove Duplicates from Sorted List II 2 | https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/ 3 | 4 | ### 思路 5 | 重要的是想清楚需要的是什么,侦测的是什么 6 | 侦测的是如果 cur.val == cur.next.val,如果没有next的话,就说明没有重复 7 | 8 | 如果有重复的话,需要当前重复的之前的点和之后的点 9 | 10 | 并且要处理好边界条件,就是尾部是null的时候。 11 | #### 代码 JavaScript 12 | 13 | ```JavaScript 14 | var deleteDuplicates = function(head) { 15 | if(!head || !head.next) return head; 16 | const dummy = new ListNode(-1, head) 17 | let p1 = dummy, p2 = head 18 | while(p2 && p2.next){ 19 | if(p2.next.val != p2.val){ 20 | p1 = p1.next 21 | p2 = p2.next 22 | }else if(p2.next.val == p2.val){ 23 | let curVal = p2.val 24 | while(p2 && p2.val == curVal) p2= p2.next 25 | p1.next = p2 26 | } 27 | } 28 | 29 | return dummy.next 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 时间复杂度:O(n)
36 | 空间复杂度:O(1) -------------------------------------------------------------------------------- /Basic200II/LC88. Merge Sorted Array.md: -------------------------------------------------------------------------------- 1 | ## LC 88. Merge Sorted Array 2 | https://leetcode-cn.com/problems/merge-sorted-array/ 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | var merge = function(nums1, m, nums2, n) { 12 | let a = m - 1, p = m + n - 1, b = n - 1 13 | 14 | while(a < p){ 15 | if(b < 0){ 16 | nums1[p] = nums1[a] 17 | a-- 18 | p-- 19 | } 20 | else if(a < 0){ 21 | nums1[p] = nums2[b] 22 | p-- 23 | b-- 24 | } 25 | else if(nums1[a] < nums2[b]){ 26 | nums1[p] = nums2[b] 27 | b-- 28 | p-- 29 | }else if(nums1[a]>= nums2[b]){ 30 | nums1[p] = nums1[a] 31 | p-- 32 | a-- 33 | } 34 | } 35 | 36 | }; 37 | ``` 38 | 39 | #### 复杂度分析 40 | 时间复杂度:
41 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC9. Palindrome Number.md: -------------------------------------------------------------------------------- 1 | ## LC 9. Palindrome Number 2 | 3 | ### 思路 解法副标题 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var isPalindrome = function(x) { 9 | if(x < 0) return false 10 | 11 | // 最后一位是0的不可能是true 12 | // 但0 自己可以是true 13 | if(x % 10 == 0 && x != 0) return false; 14 | 15 | let thehalf = 0 16 | while(x > thehalf){ 17 | thehalf = thehalf * 10 + x % 10 18 | x = Math.floor(x / 10) 19 | } 20 | 21 | //分别讨论x是偶数长度 x是奇数长度 比如121 那么结果就是 1 和 12 需要地板除 22 | return (x == thehalf) || (x == (Math.floor(thehalf / 10))) 23 | }; 24 | 25 | ``` 26 | 27 | #### 复杂度分析 28 | 29 | 时间复杂度:O(logN)
30 | 空间复杂度:O(1) 31 | -------------------------------------------------------------------------------- /Basic200II/LC90. Subsets II.md: -------------------------------------------------------------------------------- 1 | ## LC 90. Subsets II 2 | https://leetcode-cn.com/problems/subsets-ii/ 3 | - [回溯](#思路-回溯) 4 | 5 | ### 思路 回溯 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | var subsetsWithDup = function(nums) { 12 | const res = [] 13 | nums.sort((a,b) => a - b) 14 | var dfs = (cur, index) =>{ 15 | res.push(cur.slice()) 16 | 17 | for(let i = index; i < nums.length; i++){ 18 | if(i > index && nums[i] == nums[i - 1])continue 19 | dfs(cur.concat(nums[i]), i + 1) 20 | } 21 | } 22 | 23 | 24 | dfs([],0) 25 | 26 | return res 27 | }; 28 | ``` 29 | 30 | #### 复杂度分析 31 | 时间复杂度:
32 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/LC97. Interleaving String.md: -------------------------------------------------------------------------------- 1 | ## LC 97. Interleaving String 2 | https://leetcode-cn.com/problems/interleaving-string/ 3 | 4 | - [动态规划](#思路-动态规划) 5 | 6 | ### 思路 动态规划 7 | f[i][j] 是以s1 i 长的和s2 j长的能否组成s3. 注意前面特判`m + n !== s3.length return false` 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var isInterleave = function(s1, s2, s3) { 12 | const m = s1.length, n = s2.length; 13 | if(m + n !== s3.length) return false 14 | const f = Array.from({length: m + 1}).map(() => Array.from({length: n + 1}).fill(false)) 15 | f[0][0] = true 16 | 17 | for(let i = 0; i <= m; i++){ 18 | for(let j = 0; j <= n; j++){ 19 | const p = i + j - 1 20 | if(s3[p] === s2[j - 1]) f[i][j] = f[i][j]|| f[i][j - 1] 21 | if(s3[p] === s1[i - 1]) f[i][j] = f[i][j] ||f[i - 1][j] 22 | } 23 | } 24 | return f[m][n] 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 时间复杂度:
31 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/T/LC419. Battleships in a Board.md: -------------------------------------------------------------------------------- 1 | ## LC 419. Battleships in a Board 2 | https://leetcode-cn.com/problems/battleships-in-a-board/ 3 | ### 思路 解法副标题 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var countBattleships = function(board) { 9 | let ret = 0 10 | 11 | for(let i = 0; i < board.length; i++){ 12 | for(let j = 0; j < board[0].length; j++){ 13 | if(board[i][j] == 'X'){ 14 | if((i < 1 || board[i -1][j] !== 'X') && (j < 1 || board[i][j-1] !== 'X')){ 15 | ret++ 16 | } 17 | } 18 | } 19 | } 20 | 21 | return ret 22 | }; 23 | 24 | ``` 25 | 26 | #### 复杂度分析 27 | 时间复杂度:
28 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/WP/LC152. Maximum Product Subarray.md: -------------------------------------------------------------------------------- 1 | ## LC 152. Maximum Product Subarray 2 | 3 | - [动态规划](#思路-动态规划) 4 | 5 | ### 思路 动态规划 6 | 注意滚动数组之后要用`premax, premin`来记录改变之前的max 和min 7 | 8 | 注意dp的定义,就是现在的最大值可能由前一个的最小值或者最大值来 9 | 10 | 注意dp[i]的定义是必选`nums[i]`时候的最大值/最小值,所以需要额外变量来记录全局最大值。 11 | #### 代码 JavaScript 12 | 13 | ```JavaScript 14 | var maxProduct = function(nums) { 15 | let curmax = nums[0] 16 | let curmin = nums[0] 17 | 18 | let ret = nums[0] 19 | 20 | for(let i = 1; i < nums.length; i++){ 21 | let premax = curmax, premin = curmin 22 | curmax = Math.max(curmax * nums[i], nums[i], premin * nums[i]) 23 | curmin = Math.min(curmin * nums[i], premax * nums[i], nums[i]) 24 | ret = Math.max(ret, curmax) 25 | } 26 | 27 | return ret 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 时间复杂度:O(n)
34 | 空间复杂度:O(1) -------------------------------------------------------------------------------- /Basic200II/WP/LC443. String Compression.md: -------------------------------------------------------------------------------- 1 | ## LC 443. String Compression 2 | 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | anchor是现在的第一个,write是写的位置,read是赌的位置 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var compress = function(chars) { 11 | let anchor = write = 0 12 | for(let read = 0; read < chars.length; read++){ 13 | if(read + 1 === chars.length || chars[read + 1] !== chars[read]){ 14 | chars[write++] = chars[anchor] 15 | if(read > anchor){ 16 | for(const c of (read - anchor + 1).toString()){ 17 | chars[write++] = c 18 | } 19 | } 20 | anchor = read + 1 21 | } 22 | } 23 | 24 | return write 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 时间复杂度:
31 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/WP/LC56. Merge Intervals.md: -------------------------------------------------------------------------------- 1 | ## LC 56. Merge Intervals 2 | https://leetcode-cn.com/problems/merge-intervals/ 3 | - [模拟](#思路-模拟) 4 | 5 | ### 思路 模拟 6 | 要注意合并区间的写法已经pre-assumed 有序 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var merge = function(intervals) { 11 | intervals.sort((a,b) => a[0] - b[0]) 12 | const ret = []; 13 | let target = [intervals[0][0], intervals[0][1]] 14 | 15 | for(let i = 1; i < intervals.length; i++){ 16 | const interval = intervals[i] 17 | if(target[1] >= interval[0]){ 18 | target[0] = Math.min(target[0], interval[0]) 19 | target[1] = Math.max(target[1], interval[1]) 20 | }else{ 21 | ret.push(target) 22 | target = interval 23 | } 24 | } 25 | ret.push(target) 26 | return ret 27 | }; 28 | 29 | ``` 30 | 31 | #### 复杂度分析 32 | 时间复杂度:O(nlogn)
33 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/WP/Template.md: -------------------------------------------------------------------------------- 1 | ## LC 986. Interval List Intersections 2 | https://leetcode-cn.com/problems/interval-list-intersections/ 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var intervalIntersection = function(firstList, secondList) { 11 | const ret = []; 12 | let i = 0, j = 0; 13 | 14 | while(i < firstList.length && j < secondList.length){ 15 | const start = Math.max(firstList[i][0], secondList[j][0]) 16 | const end = Math.min(firstList[i][1], secondList[j][1]) 17 | if(start <= end) ret.push([start, end]) 18 | 19 | firstList[i][1] < secondList[j][1] ? i++ : j++ 20 | } 21 | 22 | return ret 23 | 24 | }; 25 | 26 | ``` 27 | 28 | #### 复杂度分析 29 | 时间复杂度:
30 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/剑指/review.md: -------------------------------------------------------------------------------- 1 | 剑指 Offer 11. 旋转数组的最小数字(https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/) -------------------------------------------------------------------------------- /Basic200II/剑指/剑指 Offer 06. 从尾到头打印链表.md: -------------------------------------------------------------------------------- 1 | ## 剑指 Offer 06. 从尾到头打印链表 2 | https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/ 3 | - [辅助栈法](#思路-辅助栈法) 4 | - [递归](#思路-递归) 5 | 6 | ### 思路 递归 7 | 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | 12 | var reversePrint = function(head) { 13 | if(!head) return [] 14 | return reversePrint(head.next).concat([head.val]) 15 | }; 16 | ``` 17 | 18 | #### 复杂度分析 19 | 时间复杂度:
20 | 空间复杂度: 21 | 22 | ### 思路 辅助栈法 23 | 24 | #### 代码 JavaScript 25 | 26 | ```JavaScript 27 | var reversePrint = function(head) { 28 | const res = [] 29 | while(head){ 30 | res.push(head.val) 31 | head = head.next 32 | } 33 | 34 | return res.reverse() 35 | }; 36 | 37 | ``` 38 | 39 | #### 复杂度分析 40 | 时间复杂度:
41 | 空间复杂度: 42 | -------------------------------------------------------------------------------- /Basic200II/剑指/剑指 Offer 25. 合并两个排序的链表.md: -------------------------------------------------------------------------------- 1 | ## 剑指 Offer 25. 合并两个排序的链表 2 | https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/ 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 也可以把判空逻辑放在外面,直接接上 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var mergeTwoLists = function(l1, l2) { 11 | const dummyHead = new ListNode(0) 12 | let cur = dummyHead; 13 | let p1 = l1, p2 = l2 14 | 15 | while(p1 || p2){ 16 | if(!p2){ 17 | cur.next = p1 18 | p1 = p1.next 19 | }else if(!p1){ 20 | cur.next = p2 21 | p2 = p2.next 22 | }else if(p1.val < p2.val){ 23 | cur.next = p1 24 | p1 = p1.next 25 | }else{ 26 | cur.next = p2 27 | p2 = p2.next 28 | } 29 | cur = cur.next 30 | } 31 | 32 | return dummyHead.next 33 | }; 34 | 35 | ``` 36 | 37 | #### 复杂度分析 38 | 时间复杂度:O(M+N)
39 | 空间复杂度:O(1) 40 | -------------------------------------------------------------------------------- /Basic200II/面试题 02.05. Sum Lists LCCI.md: -------------------------------------------------------------------------------- 1 | ## 面试题 02.05. Sum Lists LCCI 2 | https://leetcode-cn.com/problems/sum-lists-lcci/ 3 | - [朴素](#思路-朴素) 4 | 5 | ### 思路 朴素 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var addTwoNumbers = function(l1, l2) { 11 | const dummy = new ListNode(-1) 12 | 13 | let p1 = l1, p2 = l2, carry = false 14 | let curNode = dummy 15 | while(p1 || p2 || carry){ 16 | let p1val = p1 ? p1.val : 0 17 | if(p1) p1 = p1.next 18 | let p2val = p2 ? p2.val : 0 19 | if(p2) p2 = p2.next 20 | let cur = p1val + p2val 21 | 22 | if(carry){ 23 | cur++ 24 | carry = false 25 | } 26 | 27 | if(cur >= 10){ 28 | carry = true 29 | cur = cur % 10 30 | } 31 | 32 | curNode.next = new ListNode(cur) 33 | curNode = curNode.next 34 | } 35 | 36 | return dummy.next 37 | }; 38 | 39 | ``` 40 | 41 | #### 复杂度分析 42 | 时间复杂度:
43 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/面试题 08.06. Hanota LCCI.md: -------------------------------------------------------------------------------- 1 | ## LC 面试题 08.06. Hanota LCCI 2 | 3 | - [分治](#思路-分治) 4 | 5 | ### 思路 分治 6 | 按照分治思路,把问题分解到 n == 1 直接 从 a -> c 7 | 然后再把问题划分成两部分,移动n - 1 和移动最后一个 8 | 步骤如下: 9 | 1. 移动n - 1 到 a -> b 10 | 2. 移动n 到 a -> c 11 | 3. 移动 b->c 12 | #### 代码 JavaScript 13 | 14 | ```JavaScript 15 | var hanota = function(A, B, C) { 16 | 17 | return move(A.length, A, B, C) 18 | }; 19 | 20 | var move = function(n, A, B, C){ 21 | if(n == 1){ 22 | C.push(A.pop()) 23 | }else{ 24 | move(n - 1, A, C, B) 25 | move(1, A, B, C) 26 | move(n - 1, B, A, C) 27 | } 28 | } 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 34 | 时间复杂度:O(2^N - 1) 当k = 1 的时候,只需要移动一次,是1;当有k个盘子的时候,分三步解决问题。第一步和第三步都相当于移动k个盘子的问题,第二步是O(1),所以此时 2 * (2^k -1) + 1
35 | 空间复杂度: 36 | -------------------------------------------------------------------------------- /Basic200II/面试题 08.09. 括号.md: -------------------------------------------------------------------------------- 1 | ## 面试题 08.09. 括号 2 | https://leetcode-cn.com/problems/bracket-lcci/ 3 | - [回溯](#思路-回溯) 4 | 5 | ### 思路 回溯 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var generateParenthesis = function(n) { 11 | const ret =[] 12 | const bt = (left, right, cur)=> { 13 | if(right > left || left > n) return; 14 | if(cur.length === n * 2){ 15 | ret.push(cur.slice().join('')) 16 | return 17 | } 18 | 19 | bt(left + 1, right, cur.concat('(')) 20 | bt(left , right+ 1, cur.concat(')')) 21 | 22 | 23 | } 24 | bt(0,0,[]) 25 | return ret 26 | }; 27 | 28 | ``` 29 | 30 | #### 复杂度分析 31 | 时间复杂度:
32 | 空间复杂度: -------------------------------------------------------------------------------- /Basic200II/面试题 16.19. 水域大小.md: -------------------------------------------------------------------------------- 1 | ## 面试题 16.19. 水域大小 2 | https://leetcode-cn.com/problems/pond-sizes-lcci/ 3 | - [DFS](#思路-DFS) 4 | 5 | ### 思路 DFS 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var pondSizes = function(land) { 11 | const m = land.length, n = land[0].length; 12 | const dfs = (x,y) => { 13 | if(x < 0 || y < 0 || x >= m || y >= n || land[x][y] !== 0) return 0; 14 | 15 | let area = 1 16 | land[x][y] = '' 17 | area += dfs(x + 1, y) + dfs(x + 1, y - 1) + dfs(x + 1, y + 1) + dfs(x, y + 1) + dfs(x, y - 1)+ dfs(x - 1, y - 1) + dfs(x - 1, y + 1)+ dfs(x - 1, y) 18 | 19 | return area 20 | } 21 | const ret = [] 22 | for(let i = 0; i < m; i++){ 23 | for(let j = 0; j < n; j++){ 24 | if(land[i][j] === 0){ 25 | ret.push(dfs(i,j)) 26 | } 27 | } 28 | } 29 | 30 | return ret.sort((a,b) => a- b) 31 | }; 32 | 33 | ``` 34 | 35 | #### 复杂度分析 36 | 时间复杂度:
37 | 空间复杂度: -------------------------------------------------------------------------------- /JavaScript/promise.js: -------------------------------------------------------------------------------- 1 | const myPromise = new Promise((resolve, reject) => { 2 | setTimeout(() => { 3 | resolve(console.log('food')); 4 | }, 1000); 5 | }); 6 | -------------------------------------------------------------------------------- /JavaScript/readme.md: -------------------------------------------------------------------------------- 1 | 一些关于JavaScript的考点 2 | 3 | promise -------------------------------------------------------------------------------- /LeetCodeHeapAPI.md: -------------------------------------------------------------------------------- 1 | # LeetCode JavaScript PriorityQueue API 2 | 3 | ```JavaScript 4 | const maxHeap = new MaxPriorityQueue(); 5 | const minHeap = new MinPriorityQueue(); 6 | 7 | // enqueue O(logN) 8 | maxHeap.enqueue('element', 'priority') //0 returns to errors 9 | maxHeap.dequeue() //=> {element: 11, priority: 12} 10 | maxHeap.dequeue()['element'] //=> 11 11 | maxHeap.front() //peak root 12 | maxHeap.isEmpty() 13 | maxHeap.size() 14 | maxHeap.toArray() //? not sure 15 | ``` 16 | -------------------------------------------------------------------------------- /NotesBasedOnCategories/Bitwise.md: -------------------------------------------------------------------------------- 1 | # Bitwise Operation 位运算 2 | 3 | | 符号 | 描述 | 运算规则 | 4 | |-------|------|---------| 5 | | & | 与 | 两个位都为 1 时,结果才为 1 | 6 | | \ | 或 | 两个位都为 0 时,结果才为 0 | 7 | | ^ | 异或 | 两个位相同为 0,相异为 1 | 8 | | ~ | 取反 | 0 变 1,1 变 0 | 9 | | << | 左移 | 各二进位全部左移若干位,高位丢弃,低位补 0 | 10 | | >> | 右移 | 各二进位全部右移若干位,对无符号数,高位补 0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补 0(逻辑右移)| 11 | 12 | 13 | ### & 14 | ```JavaScript 15 | 偶数 & 1 = 0 16 | 奇数 & 1 = 1 17 | 18 | num & 1 = num; 19 | num & 0 = 0; 20 | 21 | bitmask &= -bitmask 把二进制中最右边的1保留,其他均为0 22 | ``` 23 | 24 | ### ^ 25 | ``` 26 | 27 | num ^ 0 = num; 28 | num ^ num = 0; 29 | num ^ 1 = ~num 30 | 31 | 32 | a ^ b ^ c = a ^ c ^ b 33 | ``` 34 | 35 | 36 | ### << 和 >> 37 | 38 | ```JavaScript 39 | 1 << num 等于 2 ** num 40 | 41 | 42 | num >> 1 等于 Math.floor(num / 2) 43 | 44 | mid = l + ((r - l) >> 1) 45 | 46 | ``` -------------------------------------------------------------------------------- /NotesBasedOnCategories/Hashtable.md: -------------------------------------------------------------------------------- 1 | Hashtable 2 | 3 | ## 应用 - 原地哈希 4 | 5 | (LC448)[https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/] 6 | (448我的解)[https://github.com/lilyzhaoyilu/LeetCode-Notes/blob/master/Basic200II/LC448.%20Find%20All%20Numbers%20Disappeared%20in%20an%20Array.md] 7 | 进阶 8 | (面试题 17.19. 消失的两个数字)[https://leetcode-cn.com/problems/missing-two-lcci/] -------------------------------------------------------------------------------- /NotesBasedOnCategories/二维图快速编码.md: -------------------------------------------------------------------------------- 1 | Give unique index to 2d array matrixs 2 | 3 | 对于 row * col 的matrix,任意的(i,j)可以使用 `i * col + j`转化成独特编码;反过来恢复只需要 4 | `i = idx / col` 5 | `j = idx % col` 6 | 7 | 8 | n = 5 9 | ``` 10 | [ 11 | [ 0, 1, 2, 3, 4 ], 12 | [ 5, 6, 7, 8, 9 ], 13 | [ 10, 11, 12, 13, 14 ], 14 | [ 15, 16, 17, 18, 19 ], 15 | [ 20, 21, 22, 23, 24 ] 16 | ] 17 | ``` 18 | 19 | 20 | 二维图编码0-8 21 | `box_index = Math.floor(row / 3) * 3 + Math.floor(col / 3)` -------------------------------------------------------------------------------- /NotesBasedOnCategories/划重点.md: -------------------------------------------------------------------------------- 1 | 重点放在**Graph**, **Tree**, **Recursion**, **Linked List**,**binary search**上。 2 | 3 | DP感觉投入产出比一般,我这次是一道DP也没遇上。 4 | 5 | Graph要尤其滚瓜烂熟,DFS, BFS,Topo sort, Bipartite,Dijkstra, union find这几个算法要可以不动脑子写出来。尤其是union find这个平时根本用不到的数据结构,写法和时间复杂度要弄懂。我三次面谷歌每次都有union find的题。。 6 | 7 | Tree的话主要练习inorder和postorder traversal。 8 | 9 | Linked list要熟练运用slow fast pointer和dummy head pointer。 10 | 11 | binarysearch建议用two pointer,注意边界条件。结束条件是l<= r还是l< r?结束以后是returnl还是r? 12 | 13 | 这一步做完了以后应该对各种算法题都有了一些基础,不少题都可以看一眼就大概知道解法大概是什么。这个时候就要用大量练习来巩固和熟练。我个人是直接开始刷leetcode 上FB tag的题,总共大概三百来道,基本上各种算法都能覆盖。对于第一遍没做出来的题,记在一个list里,第二遍就只做这个list里的题。前后大概花了两个月。事实证明只要为FB准备足够了,大部分公司都可以handle 了。FB最终面试题也基本都是这些tag里的题 14 | 15 | 来源:地里某个贴 -------------------------------------------------------------------------------- /NotesBasedOnCategories/双指针.md: -------------------------------------------------------------------------------- 1 | var partition = function(head, x) { 2 | if(!head) return head; 3 | 4 | let p = q = head; 5 | 6 | while(p){ 7 | if(p.val < x){ 8 | let temp = p.val 9 | p.val = q.val 10 | q.val = temp 11 | p = p.next 12 | q = q.next 13 | }else{ 14 | p = p.next 15 | } 16 | } 17 | 18 | return head 19 | }; -------------------------------------------------------------------------------- /NotesBasedOnCategories/快速幂.md: -------------------------------------------------------------------------------- 1 | 2 | 这个0 和1都会return true 3 | ``` 4 | bool IsPowerOfTwo(ulong x) 5 | { 6 | return (x & (x - 1)) == 0; 7 | } 8 | 9 | ``` -------------------------------------------------------------------------------- /NotesBasedOnCategories/排列组合.md: -------------------------------------------------------------------------------- 1 | ## Permutation 全排列 2 | 3 | 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。 4 | 当m=n时所有的排列情况叫全排列。 5 | 公式:全排列数f(n)=n!(定义0!=1) 6 | 1,2,3 7 | 1,3,2 8 | 2,1,3 9 | 2,3,1 10 | 3,1,2 11 | 3,2,1 12 | 一共 3 x 2 x 1 = 6 种,每一个数字开头的排列有n-1种。 13 | 14 | ### 全排列字典序法 -------------------------------------------------------------------------------- /NotesBasedOnCategories/数学知识.md: -------------------------------------------------------------------------------- 1 | # 数学知识 2 | 3 | 4 | 1. 奇偶性 5 | 奇数 + 偶数 = 奇数 6 | 偶数 + 偶数 = 偶数 7 | 8 | 2. 线性变换 9 | 指有{a,b,c} => {ax + z , bx + z, cx + z} 10 | 11 | 3. 对于从1到N的所有整数,奇数个数为 `(N + 1) / 2`,偶数个数为`N / 2` 12 | 13 | 4. 求一个数组里两个数差的绝对值是否小于target,可以按照桶排序一样,所有数字floor除以`target+ 1`;在一个桶里的就是差绝对值小于`target + 1` 14 | https://github.com/azl397985856/leetcode/blob/master/problems/220.contains-duplicate-iii.md -------------------------------------------------------------------------------- /NotesBasedOnCategories/旋转matrix.md: -------------------------------------------------------------------------------- 1 | ```JavaScript 2 | var rotate = function(matrix) { 3 | let n = matrix.length 4 | const ans = new Array(n).fill(0).map(() => new Array(n).fill(0)) 5 | for(let i = 0; i < n; i++){ 6 | for(let j = 0; j < n; j++){ 7 | ans[j][n - i - 1] = matrix[i][j] 8 | } 9 | } 10 | } 11 | ``` 12 | 13 | `newMatrix[col][n - row - 1] = matrix[row][col]` 14 | 15 | 或者原地反转 16 | ``` 17 | var rotate = function(matrix) { 18 | const n = matrix.length; 19 | // 水平翻转 20 | for (let i = 0; i < Math.floor(n / 2); i++) { 21 | for (let j = 0; j < n; j++) { 22 | [matrix[i][j], matrix[n - i - 1][j]] = [matrix[n - i - 1][j], matrix[i][j]]; 23 | } 24 | } 25 | // 主对角线翻转 26 | for (let i = 0; i < n; i++) { 27 | for (let j = 0; j < i; j++) { 28 | [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]]; 29 | } 30 | } 31 | }; 32 | 33 | ``` -------------------------------------------------------------------------------- /Template.md: -------------------------------------------------------------------------------- 1 | ## LC 2 | 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | 12 | ``` 13 | 14 | #### 复杂度分析 15 | 时间复杂度:
16 | 空间复杂度: -------------------------------------------------------------------------------- /TemplateLCPP5.md: -------------------------------------------------------------------------------- 1 | ## lcpp5 D LC 2 | 3 | - [解法副标题](#思路-解法副标题) 4 | 5 | ### 思路 解法副标题 6 | 7 | #### 代码 CPP 8 | 9 | ```cpp 10 | 11 | 12 | ``` 13 | 14 | #### 复杂度分析 15 | 时间复杂度:
16 | 空间复杂度: -------------------------------------------------------------------------------- /archive_letcodepp2/W1ArrayStack/W1D1LC66.md: -------------------------------------------------------------------------------- 1 | ### To-do 2 | 3 | 4 | ### 思路 5 | 从array的最后一位开始往前遍历: 6 | 1)如果查到最后一位元素是9,计数一次,并且从array中删除 7 | 2)如果查到最后一位元素不是9,退出循环 8 | 9 | 在array中把最后一位数(保证不是9)加一,并且把之前删掉的元素个数补回成0 10 | 11 | ### 代码 12 | ``` Ruby 13 | def plus_one(digits) 14 | count = 0 15 | 16 | loop do 17 | break unless digits.last == 9 18 | digits.pop 19 | count +=1 20 | end 21 | 22 | digits += [digits.pop.to_i + 1] + ([0] * count) 23 | 24 | 25 | end 26 | ``` 27 | ### 复杂度分析 28 | 时间复杂度:O(n) 29 | 空间复杂度:O(1) 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /archive_letcodepp2/W1ArrayStack/W1D2LC821.md: -------------------------------------------------------------------------------- 1 | ### To-do 2 | 3 | ### 思路 4 | 1)遍历找出所有c的位置,并且记录在memo中 5 | 2)再次遍历长度为s的array,计算出每个index到c的最小绝对值(即最短距离) 6 | 7 | ### 代码 8 | ``` Ruby 9 | def shortest_to_char(s, c) 10 | memo = Hash.new([]) 11 | s.each_char.with_index{|char,i| memo[c] += [i] if char == c } 12 | (0...s.size).map{|index| min(index, memo[c])} 13 | end 14 | 15 | def min(num, memo_arr) 16 | target =(num - memo_arr[-1]).abs 17 | memo_arr.each do |ele| 18 | diffrence = (num - ele).abs 19 | target = diffrence if diffrence < target 20 | end 21 | target 22 | end 23 | 24 | ``` 25 | ### 复杂度分析 26 | 时间复杂度:O(n^2) 27 | 空间复杂度:O(n) 28 | 29 | -------------------------------------------------------------------------------- /archive_letcodepp2/W1ArrayStack/notes.md: -------------------------------------------------------------------------------- 1 | Nov.5th 2020 2 | 3 | #### To do 4 | 1) 单调栈https://mp.weixin.qq.com/s/Mb8PAxMj2KLTQ1QrCh8XAA 并且重温:C768 5 | 2)优化D1-D4题解 6 | 2.1 D3 - 前缀和 (查找讲义,查找Google,再对应原题 7 | 2.2 D2 - 第二步,优化 再次遍历 8 | 2.3 D4 - solve using stack 9 | 3)理解定义 right shift ,LC150,maybe ask Ricky? 10 | 11 | 12 | #### Review in the future 13 | stack, 前缀和, 优化, 单调栈 14 | -------------------------------------------------------------------------------- /archive_letcodepp2/W2LinkedList/D10LC142.md: -------------------------------------------------------------------------------- 1 | ## LC 142 2 | ### todo 3 | 1)快指针走的路程是慢指针的两倍,两指针相遇时慢指针一定没有走完 前缀 + loop(?为啥) 4 | 2)为什么safe navigation operator (&.)在这题里用不了,是LC的问题么- 。- 5 | 6 | ### 思路 7 | 参考官方题解 8 | 快慢指针 9 | 快指针走的路程是慢指针的两倍,两指针相遇时慢指针一定没有走完 前缀 + loop(?为啥) 10 | 在两指针相遇的时候:慢指针到入口的距离等于头到入口的距离(a = c + (n-1)(b+c)) 11 | 12 | 13 | ### 代码 14 | ``` Ruby 15 | def detectCycle(head) 16 | return nil if head.nil? || head.next.nil? 17 | 18 | fastPointer, slowPointer, ptr = head.next.next, head.next, head 19 | 20 | until fastPointer == slowPointer 21 | slowPointer = slowPointer.next 22 | return nil unless fastPointer && fastPointer.next && fastPointer.next.next 23 | fastPointer = fastPointer.next.next 24 | end 25 | 26 | until ptr == slowPointer 27 | ptr = ptr.next 28 | slowPointer = slowPointer.next 29 | end 30 | 31 | ptr 32 | end 33 | ``` 34 | ### 复杂度分析 35 | 时间复杂度:O(n) 36 | 空间复杂度:O(1) 37 | 38 | 39 | -------------------------------------------------------------------------------- /archive_letcodepp2/W2LinkedList/D11LC160.md: -------------------------------------------------------------------------------- 1 | ## LC 160 2 | ### todo 3 | 4 | 5 | ### 思路 6 | 第一遍存入hash,第二遍找有没有一样滴 7 | 8 | ### 代码 9 | ``` Ruby 10 | def getIntersectionNode(headA, headB) 11 | memo = Hash.new([]) 12 | until headA.nil? 13 | memo[headA.val] +=[headA] 14 | headA = headA.next 15 | end 16 | 17 | until headB.nil? 18 | return headB if memo[headB.val].include?(headB) 19 | headB = headB.next 20 | end 21 | 22 | nil 23 | 24 | end 25 | ``` 26 | ### 复杂度分析 27 | 时间复杂度:O(n+m) 28 | 空间复杂度:O(n) 29 | 30 | ### 思路 31 | 用双指针,two pointers 32 | A + overlapped + B == B + overlapped + A 33 | 如果不相交,那么在走到尾部时 nil == nil 会停止 34 | 35 | ### 代码 36 | ``` Ruby 37 | def getIntersectionNode(headA, headB) 38 | pointerA, pointerB = headA, headB 39 | until pointerA == pointerB 40 | pointerA = pointerA.nil? ? headB : pointerA.next 41 | pointerB = pointerB.nil? ? headA : pointerB.next 42 | end 43 | pointerA 44 | end 45 | ``` 46 | ### 复杂度分析 47 | 时间复杂度:O(n+m) 48 | 空间复杂度:O(1) 49 | -------------------------------------------------------------------------------- /archive_letcodepp2/W2LinkedList/D7LC24.md: -------------------------------------------------------------------------------- 1 | ## LC 24 2 | Swap nodes 3 | ### 思路 4 | 迭代法 新建一个ListNode instance 5 | 注:数据结构是 dummyhead->node1->node2->node3->node4 6 | ### 代码 7 | ``` Ruby 8 | def swap_pairs(head) 9 | 10 | dummyhead = ListNode.new 11 | dummyhead.next = head 12 | temp = dummyhead 13 | 14 | while temp.next && temp.next.next 15 | node1 = temp.next 16 | node2 = temp.next.next 17 | 18 | temp.next = node2 19 | node1.next = node2.next 20 | node2.next = node1 21 | temp = node1 22 | end 23 | 24 | dummyhead.next 25 | end 26 | ``` 27 | ### 复杂度分析 28 | 时间复杂度:O(N) 29 | 空间复杂度:O(1) 30 | 31 | 32 | ### 思路 33 | 递归 Recursion 34 | 在原有的NodeList里改变位置 35 | ### 代码 36 | ``` Ruby 37 | def swap_pairs(head) 38 | return head if head.nil? || head.next.nil? 39 | 40 | newHead = head.next 41 | head.next = swap_pairs(newHead.next) 42 | newHead.next = head 43 | newHead 44 | 45 | end 46 | ``` 47 | ### 复杂度分析 48 | 时间复杂度:O(N) 49 | 空间复杂度:O(N) -------------------------------------------------------------------------------- /archive_letcodepp2/W2LinkedList/D8LC61.md: -------------------------------------------------------------------------------- 1 | ## LC 61 2 | 3 | ### 思路 4 | 1)形成圆环并且统计数ListNode长度 5 | 2)找到新head和tail并且切开圆环 6 | 7 | 难点:搞清楚到底是几... 8 | ### 代码 9 | ``` Ruby 10 | def rotate_right(head, k) 11 | return head if head.nil? || head.next.nil? 12 | return head if k == 0 13 | current = head 14 | count = 1 15 | 16 | until current.next.nil? 17 | current = current.next 18 | count += 1 19 | end 20 | 21 | current.next = head 22 | 23 | num = (k % count) 24 | newtail = head 25 | 26 | (count - num - 1 ).times do 27 | newtail = newtail.next 28 | end 29 | 30 | newhead = newtail.next 31 | newtail.next = nil 32 | 33 | newhead 34 | end 35 | ``` 36 | ### 复杂度分析 37 | 时间复杂度:O($N^2$) 38 | 空间复杂度:O(1) 39 | 40 | 41 | -------------------------------------------------------------------------------- /archive_letcodepp2/W2LinkedList/D9LC109.md: -------------------------------------------------------------------------------- 1 | ## LC 109 2 | 3 | ### 思路 4 | 类似于merge sort 5 | 6 | ### todo 7 | 1)复习两种class的交换,明确是哪一种class 8 | 2)找寻更优解 9 | 3)二叉树是怎么算空间复杂的? 10 | 4)看https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/solution/you-xu-lian-biao-zhuan-huan-er-cha-sou-suo-shu-1-3/ 11 | ### 代码 12 | ``` Ruby 13 | def sorted_list_to_bst(head) 14 | tree!(head,nil) 15 | end 16 | 17 | def tree!(left, right) #Listnodes 18 | return nil if left == right 19 | mid = median(left, right) 20 | root = TreeNode.new(mid.val) 21 | root.left = tree!(left, mid) 22 | root.right = tree!(mid.next, right) 23 | root 24 | end 25 | 26 | def median(head,tail) 27 | fast, slow = head, head 28 | 29 | until (fast == tail) || (fast.next == tail ) 30 | fast = fast.next.next 31 | slow = slow.next 32 | end 33 | slow 34 | end 35 | end 36 | ``` 37 | ### 复杂度分析 38 | 时间复杂度:O(nlogn) 39 | 空间复杂度:O(nlogn) 40 | 41 | 42 | -------------------------------------------------------------------------------- /archive_letcodepp2/W2LinkedList/notes.md: -------------------------------------------------------------------------------- 1 | ### todo 2 | 3 | minheap/maxheap 973. K Closest Points to Origin -------------------------------------------------------------------------------- /archive_letcodepp2/W3Trees/D14LC100.md: -------------------------------------------------------------------------------- 1 | ## LC 104 2 | 3 | ### 思路 4 | 递归,比较每两个应该相同的node 5 | ### 代码 6 | ``` JavaScript 7 | 8 | var isSameTree = function (p, q) { 9 | if (!p && !q) return ture; 10 | if (!p||!q||p.val !== q.val) return false; 11 | 12 | return isSameTree(p.left,q.left) && isSameTree(p.right,q.right); 13 | 14 | ``` 15 | ### 复杂度分析 16 | 时间复杂度:$O(N)$,N 为二叉树的节点数。 17 | 空间复杂度:$O(N)$ 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /archive_letcodepp2/W3Trees/D15LC129.md: -------------------------------------------------------------------------------- 1 | ## LC 104 2 | 3 | ### todo 4 | 1)check guanfang 5 | 2) do it in traditional BFS+iteration 6 | 3) do it in trad. DFS 7 | ### 思路 8 | 递归 9 | ### 代码 10 | ``` JavaScript 11 | 12 | var sumNumbers = function(root) { 13 | return helper(root, 0); 14 | }; 15 | 16 | var helper = function(root, i){ 17 | if(root === null) return 0; 18 | let value = root.val + (i * 10); 19 | if (root.left === null && root.right === null)return value; 20 | return helper(root.left, value) + helper(root.right, value); 21 | } 22 | 23 | ``` 24 | ### 复杂度分析 25 | 时间复杂度:$O(N)$,N 为二叉树的节点数。 26 | 空间复杂度:$O(N)$ 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /archive_letcodepp2/W3Trees/D18 NEEDTODO.md: -------------------------------------------------------------------------------- 1 | ## LC 2 | 3 | ### todo 4 | 5 | ### 思路 6 | 7 | ### 代码 8 | ``` JavaScript 9 | 10 | 11 | 12 | ``` 13 | ### 复杂度分析 14 | -------------------------------------------------------------------------------- /archive_letcodepp2/W3Trees/notes.md: -------------------------------------------------------------------------------- 1 | Nov.13th 2020 2 | 3 | #### To do 4 | 1) D14LC100 5 | 前序+中序遍历 确定一棵树 6 | 7 | 8 | 9 | #### Review in the future 10 | 树 11 | 前序 中序 后序 12 | DFS BFS 13 | 搭建本地树的平台 14 | 基本树的题 15 | Lucifer的树专题+讲义 -------------------------------------------------------------------------------- /archive_letcodepp2/W4Hash/D19LC1.md: -------------------------------------------------------------------------------- 1 | ## LC 1 TWO SUM 2 | 3 | ### 思路 4 | 1)建立map(hash in Ruby) 5 | 1.1 注意JS (JS is weird...) 6 | (map[2] = 5) ==> Map { '2': 5 } where '2' is a string 7 | map.set(1,2) ==> Map {1 => 2} where 1 is a integer 8 | 类似的 map[2] 会查询"2" 9 | map.has(1) 会查询1 10 | map[2] => 5 11 | map.get(1) => 2 12 | map[0] & map.get(10) => undefined 13 | 2)如果map里有答案需要的key,则返回现在的index 和 map.get(key) //查询时间是O(1) 14 | 如果没有,则map.set(nums[i], index) 15 | 3)所以时间是O(n),因为遍历nums的时间是O(n) 16 | ### 代码 17 | ``` JavaScript 18 | var twoSum = function (nums, target) { 19 | let memo = new Map(); 20 | for (i = 0; i < nums.length; i++) { 21 | if (!memo.has(target - nums[i])) { 22 | memo.set(nums[i], i); 23 | } else { 24 | return [memo.get(target - nums[i]), i]; 25 | }}}; 26 | 27 | ``` 28 | ### 复杂度分析 29 | 时间复杂度:O(n), n 为nums长度 30 | 空间复杂度:O(n), n 为nums长度 -------------------------------------------------------------------------------- /archive_letcodepp2/W4Hash/D24TODO.md: -------------------------------------------------------------------------------- 1 | ## LC 2 | 3 | ### 思路 4 | 5 | 6 | ### 代码 7 | ``` JavaScript 8 | 9 | 10 | ``` 11 | ### 复杂度分析 12 | 时间复杂度: 13 | 空间复杂度: -------------------------------------------------------------------------------- /archive_letcodepp2/W4Hash/MinHeapMaxHeap.md: -------------------------------------------------------------------------------- 1 | ## Min Heap 小顶堆/最小堆 & Max Heap 大顶堆 2 | https://www.educative.io/edpresso/min-heap-vs-max-heap 3 | ### Definition 4 | Min and Max heaps are complete binary trees with some unique properties. 5 | complete binary tree: https://web.cecs.pdx.edu/~sheard/course/Cs163/Doc/FullvsComplete.html#:~:text=A%20full%20binary%20tree%20(sometimes,as%20far%20left%20as%20possible 6 | 7 | 8 | How are Min/Max Heaps represented? 9 | A Min/Max heap is typically represented as an array. 10 | 11 | Arr[0] Returns the root node. 12 | Arr[(i-1)/2] Returns the parent node. 13 | Arr[(2*i)+1] Returns the left child node. 14 | Arr[(2*i)+2] Returns the right child node. 15 | 16 | ### to-do 17 | index calculation when representing a b-tree in arrays. -------------------------------------------------------------------------------- /archive_letcodepp2/W4Hash/hashNotes.md: -------------------------------------------------------------------------------- 1 | ## Hash Notes 2 | 3 | ### Terms 4 | 5 | #### 抽屉原理 Pigeonhole principle 6 | 如果有n个抽屉,要放n+1个苹果,则至少有一个抽屉里有1+1 个苹果. 7 | 8 | #### 并查集 ???? 9 | 在计算机科学中,并查集是一种树型的数据结构,用于处理一些不交集(Disjoint Sets)的合并及查询问题。 有一个联合-查找算法(union-find algorithm)定义了两个用于此数据结构的操作: Find :确定元素属于哪一个子集。 它可以被用来确定两个元素是否属于同一子集。 10 | 11 | #### 离散 dispersion 12 | In statistics, dispersion is the extent to which a distribution is stretched or squeezed. Common examples of measures of statistical dispersion are the variance, standard deviation, and interquartile range. -------------------------------------------------------------------------------- /archive_letcodepp2/W6D34BinaryTree/binaryTrees.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/archive_letcodepp2/W6D34BinaryTree/binaryTrees.md -------------------------------------------------------------------------------- /archive_letcodepp2/W6D35ReverseLinkedList/TODOLC25.md: -------------------------------------------------------------------------------- 1 | ## LC 25 2 | 3 | https://leetcode-cn.com/problems/reverse-nodes-in-k-group/ 4 | 5 | ### 思路 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | 11 | 12 | ``` 13 | 14 | ### 复杂度分析 15 | 16 | 时间复杂度: 17 | 空间复杂度: 18 | -------------------------------------------------------------------------------- /archive_letcodepp2/W6D36位运算/LC78Subsets.md: -------------------------------------------------------------------------------- 1 | ## LC 78 2 | 3 | https://leetcode-cn.com/problems/subsets/ 4 | 5 | ### 思路 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | 11 | 12 | ``` 13 | 14 | ### 复杂度分析 15 | 16 | 时间复杂度: 17 | 空间复杂度: 18 | -------------------------------------------------------------------------------- /archive_letcodepp2/W6D38Stack/LC20.md: -------------------------------------------------------------------------------- 1 | ## LC 20 2 | 3 | ### 思路 4 | 5 | 建立一个字典 6 | 遍历 s, 7 | 8 | - 如果遇到左边的括号,就压右边的括号入栈 9 | - 如果遇到不是左边的括号,就弹出栈(stack.pop)并且比对两者是否一致 \* 如果不一致,则返回 false 10 | 遍历结束后 11 | - 如果栈内没有剩余,则为 true 12 | - 反之,则为 false 13 | 14 | ### 代码 15 | 16 | ```Ruby 17 | def is_valid(s) 18 | memo={'('=>')','{'=>'}','['=>']'} 19 | stack = [] 20 | s.chars.each do |char| 21 | if memo[char] 22 | stack.push(memo[char]) 23 | else 24 | return false if stack.pop != char 25 | end 26 | end 27 | return stack.empty? ? true : false 28 | end 29 | 30 | 31 | ``` 32 | 33 | ### 复杂度分析 34 | 35 | 时间复杂度:O(N) 遍历一遍 36 | 空间复杂度:O(N) 最坏的情况栈的大小和 s 大小一样, N 为 s 的长度 37 | -------------------------------------------------------------------------------- /archive_letcodepp2/W6D38Stack/LC32.md: -------------------------------------------------------------------------------- 1 | ## LC32 2 | 3 | ### 思路 4 | 5 | 作者很懒,只想睡觉 6 | 7 | ### 代码 8 | 9 | ```Ruby 10 | def longest_valid_parentheses(s) 11 | return 0 if s.length == 0 12 | max = 0 13 | stack = [-1] 14 | s.each_char.with_index do |char, index| 15 | if char == "(" 16 | stack << index 17 | else 18 | stack.pop 19 | if stack.empty? 20 | stack.push(index) 21 | else 22 | max = [max, index - stack.last].max 23 | end 24 | end 25 | end 26 | max 27 | end 28 | 29 | 30 | ``` 31 | 32 | ### 复杂度分析 33 | 34 | 时间复杂度:O(N) 35 | 空间复杂度:O(N) 36 | -------------------------------------------------------------------------------- /archive_letcodepp2/W6D39Design/剑指09.md: -------------------------------------------------------------------------------- 1 | ## LC 高频 07 剑指 Offer 09. 用两个栈实现队列 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```Ruby 8 | class CQueue 9 | def initialize() 10 | @head = [] 11 | @tail = [] 12 | end 13 | 14 | 15 | =begin 16 | :type value: Integer 17 | :rtype: Void 18 | =end 19 | def append_tail(value) 20 | @tail << value 21 | end 22 | 23 | 24 | =begin 25 | :rtype: Integer 26 | =end 27 | def delete_head() 28 | daoteng if @head.empty? 29 | return @head.empty? ? -1 : @head.pop 30 | end 31 | private 32 | def daoteng() 33 | until @tail.empty? 34 | @head << (@tail.pop) 35 | end 36 | end 37 | 38 | 39 | end 40 | 41 | ``` 42 | 43 | ### 复杂度分析 44 | 45 | 时间复杂度:O(1) 平均下来 46 | 空间复杂度:O(N) 47 | -------------------------------------------------------------------------------- /archive_letcodepp2/otherQs/LC150 Ruby.md: -------------------------------------------------------------------------------- 1 | ## LC 150 2 | 3 | ### 思路 4 | 遍历tokens,1)如果遇到非运算符号字符(数字字符),则转换成数字并加入栈中 5 | 2)如果遇到运算符号字符,通过.send把它转换成function,并且取出栈中最后两个数字进行运算; 6 | 得到运算结果后,再push回栈。 7 | 8 | ### 代码 9 | ``` Ruby 10 | 11 | def eval_rpn(tokens) 12 | stack = [] 13 | operators = {"+" => "+","-" => "-","*" =>"*","/" => "/" } 14 | 15 | tokens.each do |token| 16 | if operators[token] #如果有值,则Hash的返回值不是nil 17 | num1 = stack.pop 18 | num2 = stack.pop 19 | result = num2.send(token, num1) #用.send(method_name_as_string,argument)来把字符运算符号转换成运算符号 20 | result += 1 if (token == "/") && (result < 0) && ((num2 % num1) != 0 ) 21 | stack.push(result) 22 | else 23 | stack.push(token.to_i) 24 | end 25 | end 26 | 27 | stack.last 28 | end 29 | 30 | 31 | ``` 32 | ### 复杂度分析 33 | 时间复杂度:O(N) 34 | 空间复杂度:O(N) -------------------------------------------------------------------------------- /archive_letcodepp2/otherQs/LC88 JS.md: -------------------------------------------------------------------------------- 1 | ## LC 88 2 | 3 | ### 思路 4 | 3 pointers, from the end 5 | 6 | ### 代码 7 | ``` JavaScript 8 | var merge = function(nums1, m, nums2, n) { 9 | let pointer = m + n - 1; 10 | let pointer1 = m - 1; 11 | let pointer2 = n -1; 12 | 13 | while (pointer1 >= 0 && pointer2 >= 0){ 14 | nums1[pointer--] = (nums1[pointer1] < nums2[pointer2]) ? nums2[pointer2--] :nums1[pointer1--]} 15 | while(pointer2 >= 0){ 16 | nums1[pointer--] = nums2[pointer2--]; 17 | } 18 | }; 19 | 20 | ``` 21 | ### 复杂度分析 22 | 时间复杂度:O(n) 23 | 空间复杂度:O(1) -------------------------------------------------------------------------------- /articles/airticleAssests/刷题进程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/articles/airticleAssests/刷题进程.png -------------------------------------------------------------------------------- /articles/airticleAssests/多刷模板题.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/articles/airticleAssests/多刷模板题.png -------------------------------------------------------------------------------- /articles/airticleAssests/日程截图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/articles/airticleAssests/日程截图.jpg -------------------------------------------------------------------------------- /articles/airticleAssests/狗头在办公室.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/articles/airticleAssests/狗头在办公室.jpg -------------------------------------------------------------------------------- /articles/airticleAssests/聊天截图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/articles/airticleAssests/聊天截图.png -------------------------------------------------------------------------------- /assets/DFSBinaryTreeSerializeAndDeserialize.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/assets/DFSBinaryTreeSerializeAndDeserialize.jpg -------------------------------------------------------------------------------- /assets/LC142Floyd'sCircleFinding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/assets/LC142Floyd'sCircleFinding.jpg -------------------------------------------------------------------------------- /assets/LC1439多路归并压缩.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/assets/LC1439多路归并压缩.jpg -------------------------------------------------------------------------------- /assets/LC327count部分.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/assets/LC327count部分.jpg -------------------------------------------------------------------------------- /assets/LCCN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/assets/LCCN.png -------------------------------------------------------------------------------- /assets/deskset.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/assets/deskset.jpg -------------------------------------------------------------------------------- /assets/download.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/排列公式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilyzhaoyilu/LeetCode-Notes/004a3c0149e66721261ce801c7dce2ac636ba169/assets/排列公式.png -------------------------------------------------------------------------------- /lcDaily/BinarySearchJS.md: -------------------------------------------------------------------------------- 1 | ## LC 704 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```JavaScript 8 | 9 | var search = function(nums, target) { 10 | let l = 0, r = nums.length - 1, result = -1; 11 | 12 | while(l <= r){ 13 | let mid = (l + r) >> 1; // + left? 14 | // console.log(mid) 15 | if(nums[mid] == target){ 16 | result = mid; 17 | return result; 18 | }else if(nums[mid] > target){ 19 | r = mid - 1; 20 | }else{ 21 | l = mid + 1; 22 | } 23 | } 24 | return result; 25 | }; 26 | 27 | ``` 28 | 29 | ### 复杂度分析 30 | 31 | 时间复杂度: 32 | 空间复杂度: 33 | -------------------------------------------------------------------------------- /lcDaily/LC119.md: -------------------------------------------------------------------------------- 1 | ## LC 119 2 | 3 | 递归+滚动数组 4 | 5 | ### 思路 6 | 7 | 滚动数组就是在现在的结果只跟前一个结果有关系的情况下 8 | 只保存前一层数组的数据 9 | 和现在这一层的数字 10 | 他就节约了存储空间,他就滚动了 11 | 12 | ### 代码 13 | 14 | ```JavaScript 15 | /** 16 | * @param {number} rowIndex 17 | * @return {number[]} 18 | */ 19 | var getRow = function(rowIndex) { 20 | let pre = [], cur = []; 21 | for(let i = 0; i <= rowIndex; i++){ 22 | cur = new Array(i + 1).fill(0); 23 | cur[0] = cur[i] = 1; 24 | for(let j = 1; j < i; j++){ 25 | cur[j] = pre[j - 1] + pre[j]; 26 | } 27 | pre = cur; 28 | } 29 | 30 | return pre; 31 | }; 32 | 33 | ``` 34 | 35 | ### 复杂度分析 36 | 37 | 时间复杂度:O(N^2) 38 | 空间复杂度:O(1) 不考虑返回的值的占用空间 39 | -------------------------------------------------------------------------------- /lcDaily/LC13. Roman to Integer.md: -------------------------------------------------------------------------------- 1 | ## LC 13. Roman to Integer 2 | 3 | ### 思路 4 | 5 | Notice that for Roman numbers, if the smaller one appears first, it means -- 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var romanToInt = function(s) { 11 | let ans = 0 12 | 13 | const dict = new Map(); 14 | dict.set('I', 1); 15 | dict.set('V', 5); 16 | dict.set('X', 10); 17 | dict.set('L', 50); 18 | dict.set('C', 100); 19 | dict.set('C', 100); 20 | dict.set('D', 500); 21 | dict.set('M', 1000); 22 | 23 | for(let i = 0; i < s.length; i++){ 24 | if(i != s.length - 1 && dict.get(s[i]) < dict.get(s[i + 1])){ 25 | ans -= dict.get(s[i]) 26 | }else{ 27 | ans += dict.get(s[i]) 28 | } 29 | } 30 | 31 | return ans; 32 | }; 33 | 34 | ``` 35 | 36 | #### 复杂度分析 37 | 38 | 时间复杂度: O(N)
39 | 空间复杂度:O(1) 40 | -------------------------------------------------------------------------------- /lcDaily/LC137.md: -------------------------------------------------------------------------------- 1 | ## LC 137 2 | 3 | https://leetcode-cn.com/problems/single-number-ii/ 4 | 5 | ### 思路 6 | 7 | 哈希表 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | var singleNumber = function(nums) { 13 | let memo = new Map(); 14 | for (ele of nums){ 15 | memo.set(ele, (memo.get(ele) || 0) + 1) 16 | } 17 | 18 | //这个在lc会有return错误 19 | // [...memo.entries()].forEach((ele) => { 20 | // if(ele[1] === 1){ 21 | // return ele[0]; 22 | // } 23 | // }) 24 | 25 | 26 | //这个正常 27 | for(const [key, val] of memo.entries()){ 28 | if(val === 1) return key; 29 | } 30 | }; 31 | 32 | ``` 33 | 34 | ### 复杂度分析 35 | 36 | 时间复杂度:O(N) 37 | 空间复杂度:O(N) 38 | -------------------------------------------------------------------------------- /lcDaily/LC1486. XOR Operation in an Array.md: -------------------------------------------------------------------------------- 1 | ## LC1486. XOR Operation in an Array 2 | 3 | ### 思路 4 | 5 | Naive approach 6 | 7 | ### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var xorOperation = function(n, start) { 11 | let arr = [start]; 12 | 13 | for(let i = 1; i < n; i++){ 14 | arr.push(start + 2 * i) 15 | } 16 | 17 | let res = arr.pop(); 18 | while(arr.length > 0){ 19 | let temp = arr.pop(); 20 | res = res ^ temp; 21 | } 22 | 23 | return res; 24 | }; 25 | 26 | ``` 27 | 28 | ### 复杂度分析 29 | 30 | 时间复杂度:O(N) 31 | 空间复杂度:O(N) 32 | 33 | ### 思路 34 | 35 | 优化- 其实我们不需要整个 array 36 | 我们只关注答案是什么就够了 37 | 所以可以只遍历一次,记录答案 38 | 有点类似于 dp 的滚动数组的思路 39 | 40 | ### 代码 JavaScript 41 | 42 | ```JavaScript 43 | var xorOperation = function(n, start) { 44 | let ans = start 45 | 46 | for(let i = 1; i < n; i++){ 47 | ans ^= (start + 2 * i) 48 | //ans = ans ^ (start + 2 * i) 49 | } 50 | 51 | return ans; 52 | }; 53 | ``` 54 | 55 | ### 复杂度分析 56 | 57 | 时间复杂度:O(N) 58 | 空间复杂度:O(1) 59 | -------------------------------------------------------------------------------- /lcDaily/LC153.md: -------------------------------------------------------------------------------- 1 | ## LC 153 2 | 3 | https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/ 4 | 5 | ### 思路 6 | 7 | 二分法 - 二分法的灵魂是对解空间的折半 (西法名言 8 | 首先解可能在整个 nums 中,如何折半呢 - 用二分搜索/binary search 9 | 取中点 mid 10 | 如果 nums[mid] < nums[r] 11 | 那么说明在 nums[mid+1..r]这个区间里,没有最小值,如此可以收缩窗口 12 | 反之 13 | 最小值就在窗口里 14 | 15 | ### 代码 16 | 17 | ```JavaScript 18 | var findMin = function(nums) { 19 | let l = 0, r = nums.length - 1; 20 | while(l < r){ 21 | 22 | let mid = l + ((r - l) >> 1); //mid保证不会溢出的写法 23 | 24 | if(nums[r] > nums[mid]){ 25 | r = mid; 26 | }else{ 27 | l = mid + 1; 28 | } 29 | 30 | } 31 | 32 | return nums[l] 33 | }; 34 | 35 | ``` 36 | 37 | ### 复杂度分析 38 | 39 | 时间复杂度:O(N) 遍历一次 40 | 空间复杂度:O(1) 只存储了常量 41 | -------------------------------------------------------------------------------- /lcDaily/LC160. Intersection of Two Linked Lists.md: -------------------------------------------------------------------------------- 1 | ## LC 160. Intersection of Two Linked Lists 2 | 3 | https://leetcode-cn.com/problems/intersection-of-two-linked-lists/ 4 | 5 | - [双指针](#思路-双指针) 6 | 7 | ### 思路 双指针 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var getIntersectionNode = function(headA, headB) { 13 | if(!headA || !headB) return null; 14 | let curA = headA, curB = headB 15 | while(curA != curB){ 16 | curA = curA ? curA.next : headB 17 | curB = curB ? curB.next : headA 18 | } 19 | return curA 20 | }; 21 | 22 | ``` 23 | 24 | #### 复杂度分析 25 | 26 | 时间复杂度:O(N)
27 | 空间复杂度:O(1) 28 | -------------------------------------------------------------------------------- /lcDaily/LC1736. Latest Time by Replacing Hidden Digits.md: -------------------------------------------------------------------------------- 1 | ## LC 1736. Latest Time by Replacing Hidden Digits 2 | https://leetcode-cn.com/problems/latest-time-by-replacing-hidden-digits/ 3 | 4 | ### 思路 贪心+模拟 5 | 宫水写法真棒 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var maximumTime = function(time) { 10 | let ret = '' 11 | ret += time[0] === '?' ? ((time[1] === '?' || time[1] < 4) ? '2' : '1') : time[0] 12 | ret += time[1] === '?' ? (ret[0] === '2' ? '3' : '9') : time[1] 13 | ret += ':' 14 | ret += time[3] === '?' ? '5' : time[3] 15 | ret += time[4] === '?' ? '9' : time[4] 16 | 17 | return ret 18 | }; 19 | 20 | ``` 21 | 22 | #### 复杂度分析 23 | 时间复杂度:
24 | 空间复杂度: -------------------------------------------------------------------------------- /lcDaily/LC1846. Maximum Element After Decreasing and Rearranging.md: -------------------------------------------------------------------------------- 1 | ## LC 1846. Maximum Element After Decreasing and Rearranging 2 | 3 | https://leetcode-cn.com/problems/maximum-element-after-decreasing-and-rearranging/ 4 | ### 思路 贪心 5 | 读题,arr[i]的取值范围是[1, 10 ** 9],操作只能rearrange或者减少。所以第一个必然是1. 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | 11 | var maximumElementAfterDecrementingAndRearranging = function(arr) { 12 | arr.sort((a,b) => a - b); 13 | arr[0] = 1 14 | for(let i = 1; i < arr.length; i++){ 15 | if(arr[i] - arr[i - 1] <= 1){ 16 | continue 17 | }else{ 18 | arr[i] = arr[i - 1] + 1 19 | } 20 | } 21 | 22 | return arr[arr.length - 1] 23 | }; 24 | ``` 25 | 26 | #### 复杂度分析 27 | 时间复杂度:
28 | 空间复杂度: -------------------------------------------------------------------------------- /lcDaily/LC263.md: -------------------------------------------------------------------------------- 1 | ## LC 263 2 | 3 | https://leetcode-cn.com/problems/ugly-number/ 4 | 5 | ### 思路 6 | 7 | 把题转换一个思路 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | 13 | var isUgly = function(n) { 14 | if(n <= 0){ 15 | return false; 16 | } 17 | const factors = [2,3,5]; 18 | for(factor of factors){ 19 | while(n % factor == 0){ 20 | n = n / factor; 21 | } 22 | } 23 | 24 | return n == 1; 25 | }; 26 | ``` 27 | 28 | ### 复杂度分析 29 | 30 | 时间复杂度:O(logN) 因为每次至少除以 2,所以不会多于 logN 31 | 空间复杂度:O(1) 32 | -------------------------------------------------------------------------------- /lcDaily/LC27.md: -------------------------------------------------------------------------------- 1 | ## LC 27 2 | 3 | ### 思路 4 | 5 | 双指针 6 | 左右经典双指针,左指针负责更新 7 | 8 | ### 代码 9 | 10 | ```JavaScript 11 | var removeElement = function(nums, val) { 12 | let left = 0, right = 0 13 | 14 | while(right < nums.length){ 15 | if(nums[right] !== val){ 16 | nums[left] = nums[right]; 17 | left++; 18 | } 19 | right++; 20 | } 21 | return left; 22 | 23 | }; 24 | 25 | ``` 26 | 27 | ### 复杂度分析 28 | 29 | 时间复杂度:O(N) 30 | 空间复杂度:O(1) 31 | 32 | ### 思路 33 | 34 | 双指针 35 | 左右经典双指针,从两侧走 36 | 37 | ### 代码 38 | 39 | ```JavaScript 40 | var removeElement = function(nums, val) { 41 | let left = 0, right = nums.length - 1; 42 | 43 | while(right >= left){ 44 | 45 | if(nums[left] == val){ 46 | nums[left] = nums[right]; 47 | right--; 48 | }else{ 49 | left++; 50 | } 51 | } 52 | return left; 53 | 54 | }; 55 | 56 | ``` 57 | 58 | ### 复杂度分析 59 | 60 | 时间复杂度:O(N) 61 | 空间复杂度:O(1) 62 | -------------------------------------------------------------------------------- /lcDaily/LC344.md: -------------------------------------------------------------------------------- 1 | ## LC344 2 | 3 | ### 思路 4 | 5 | DFS 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var reverseString = function(s) { 11 | if(s.length == 0) return s; 12 | 13 | var rec = function(s, left, right){ 14 | if(left >= right) return [] ; 15 | [s[left], s[right]] = [s[right], s[left]]; 16 | left++; right--; 17 | return rec(s,left,right) 18 | } 19 | 20 | let len = s.length - 1; 21 | 22 | return rec(s,0, len); 23 | }; 24 | 25 | ``` 26 | 27 | ### 复杂度分析 28 | 29 | 时间复杂度: 30 | 空间复杂度: 31 | -------------------------------------------------------------------------------- /lcDaily/LC374. Guess Number Higher or Lower.md: -------------------------------------------------------------------------------- 1 | ## LC 374. Guess Number Higher or Lower 2 | 3 | - [二分-能力检测](#思路-二分-能力检测) 4 | 5 | ### 思路 二分-能力检测 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var guessNumber = function(n) { 11 | 12 | let left = 1, right = n; 13 | while(true){ 14 | const ans = left + ((right - left) >> 1) 15 | if(guess(ans) == 0){ 16 | return ans 17 | }else if(guess(ans) == 1){ 18 | left = ans + 1 19 | }else if(guess(ans) == -1){ 20 | right = ans - 1 21 | } 22 | } 23 | }; 24 | ``` 25 | 26 | #### 复杂度分析 27 | 时间复杂度:logN
28 | 空间复杂度:1 29 | -------------------------------------------------------------------------------- /lcDaily/LC611. Valid Triangle Number.md: -------------------------------------------------------------------------------- 1 | ## LC 611. Valid Triangle Number 2 | https://leetcode-cn.com/problems/valid-triangle-number/ 3 | - [数学+排序](#思路-数学+排序) 4 | 5 | ### 思路 数学+排序 6 | 排序后的数组只要检验 a + b > c 就可以了 7 | 然后再利用双指针啪拍扁 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var triangleNumber = function(nums) { 12 | nums.sort((a,b) => a - b); 13 | let ans = 0 14 | for(let i = 0; i < nums.length; i++){ 15 | let k = i; 16 | for(let j = i + 1; j < nums.length; j++){ 17 | while( k + 1 < nums.length && nums[k + 1] < nums[i] + nums[j]) ++k; 18 | ans += Math.max(k - j, 0) 19 | } 20 | } 21 | return ans; 22 | }; 23 | 24 | ``` 25 | 26 | #### 复杂度分析 27 | 时间复杂度:
28 | 空间复杂度: -------------------------------------------------------------------------------- /lcDaily/LC664. Strange Printer.md: -------------------------------------------------------------------------------- 1 | ## LC 664. Strange Printer 2 | 3 | 学习https://leetcode-cn.com/problems/strange-printer/solution/xin-shou-pian-cong-xiao-wen-ti-zai-dao-q-qifh/ 4 | 5 | - [DP](#思路-DP) 6 | 7 | ### 思路 DP 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var strangePrinter = function(s) { 13 | const dp = Array.from({length: s.length}).map(() => Array.from({length: s.length}).fill(101)) 14 | //dp[i][j] -> 在s[i:j]打印中最少的次数 15 | for(let i= s.length -1; i >= 0; i--){ 16 | dp[i][i] = 1; 17 | for(let j = i + 1; j < s.length; j++){ 18 | if(s[i] === s[j]) 19 | dp[i][j] = dp[i][j-1] 20 | else 21 | for(let k = i; k < j; k++){ 22 | dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k+1][j]) 23 | } 24 | } 25 | } 26 | // console.log(dp) 27 | return dp[0][s.length - 1] 28 | }; 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 34 | 时间复杂度:O(N^3)
35 | 空间复杂度:O(N^2) 36 | -------------------------------------------------------------------------------- /leetcodepp3/BinarySearch/D29 LC69.md: -------------------------------------------------------------------------------- 1 | ## LC 69 2 | 3 | https://leetcode-cn.com/problems/sqrtx/ 4 | 5 | ### 思路 6 | 7 | 二分法 8 | 值得注意的是 当目标值小于等于当前值的时候 9 | 要更新 result 10 | 且 l = mid + 1 11 | 12 | ### 代码 13 | 14 | ```JavaScript 15 | var mySqrt = function(x) { 16 | let l = 0, r = x, result = -1; 17 | 18 | while(l <= r){ 19 | let mid = ((l + r) >> 1) , midsqr = mid ** 2; 20 | if(midsqr > x){ 21 | r = mid - 1; 22 | }else{ 23 | result = mid; 24 | l = mid + 1; 25 | } 26 | } 27 | 28 | return result; 29 | }; 30 | 31 | ``` 32 | 33 | ### 复杂度分析 34 | 35 | 时间复杂度:O(logX) 36 | 空间复杂度:O(1) 37 | -------------------------------------------------------------------------------- /leetcodepp3/BinarySearch/TDD32 Minimum-Light-Radius .md: -------------------------------------------------------------------------------- 1 | ## LC 2 | 3 | ### 思路 4 | 5 | 6 | ### 代码 7 | ``` JavaScript 8 | 9 | 10 | ``` 11 | ### 复杂度分析 12 | 时间复杂度: 13 | 空间复杂度: -------------------------------------------------------------------------------- /leetcodepp3/BinaryTree/D15 LC129.md: -------------------------------------------------------------------------------- 1 | ## LC 129 2 | 3 | https://leetcode-cn.com/problems/sum-root-to-leaf-numbers 4 | 5 | ### 思路 6 | 7 | DFS 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | var sumNumbers = function(root) { 13 | 14 | var dfs = function(root, prevSum){ 15 | if(!root) return 0; 16 | const sum = prevSum * 10 + root.val; 17 | if(!root.left && !root.right){return sum; 18 | }else{ 19 | return dfs(root.left,sum) + dfs(root.right, sum) 20 | } 21 | } 22 | return dfs(root,0) 23 | }; 24 | 25 | ``` 26 | 27 | ### 复杂度分析 28 | 29 | 时间复杂度:O(N) 30 | 空间复杂度:O(N) 31 | -------------------------------------------------------------------------------- /leetcodepp3/BinaryTree/D16 LC513.md: -------------------------------------------------------------------------------- 1 | ## LC 513 2 | 3 | ### 思路 4 | 5 | BFS 6 | 不是这个模板也忒好使了吧喂(#`O′) 7 | 8 | ### 代码 9 | 10 | ```JavaScript 11 | var findBottomLeftValue = function(root) { 12 | let queue = []; 13 | queue.push(root); 14 | let result; 15 | while(queue.length > 0){ 16 | let curlevel = queue; 17 | queue = []; 18 | result = curlevel[0].val; 19 | for(let i = 0; i < curlevel.length; i++){ 20 | if(curlevel[i].left) queue.push(curlevel[i].left); 21 | if(curlevel[i].right) queue.push(curlevel[i].right); 22 | } 23 | } 24 | return result; 25 | }; 26 | 27 | ``` 28 | 29 | ### 复杂度分析 30 | 31 | 时间复杂度:O(N) N 为节点数 因为访问了每个节点 32 | 空间复杂度:O(N) N 为节点数 因为有个 queue 33 | -------------------------------------------------------------------------------- /leetcodepp3/BinaryTree/LC154.md: -------------------------------------------------------------------------------- 1 | ## LC 154 2 | 3 | ### 思路 4 | 5 | 二分法 注意找准讨论情况 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | 11 | var findMin = function(nums) { 12 | if(nums.length ==1) return nums[0]; 13 | let l = 0, r = nums.length - 1; 14 | 15 | while (l < r){ 16 | let mid = l + ((r - l) >> 1); 17 | // console.log(l, mid, r) 18 | 19 | if(nums[mid] < nums[r]){ 20 | r = mid; 21 | }else if(nums[mid] > nums[r]){ 22 | l = mid + 1; 23 | }else{ 24 | r = r -1; 25 | } 26 | 27 | } 28 | // console.log(l,r) 29 | return nums[l]; 30 | }; 31 | 32 | ``` 33 | 34 | ### 复杂度分析 35 | 36 | 时间复杂度:O(N)最坏情况,一般 O(NlogN) 37 | 空间复杂度:O(1) 38 | -------------------------------------------------------------------------------- /leetcodepp3/DynamicProgramming/LC1143最长公共子序列.md: -------------------------------------------------------------------------------- 1 | ## LC 1143 最长公共子序列 2 | 3 | ### 思路 4 | 5 | DP 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var longestCommonSubsequence = function(text1, text2) { 11 | const dp = Array.from({length: text1.length + 1}).map(() => (Array.from({length: text2.length + 1}).fill(0))) 12 | //dp[i][j] 对应 text1[i - 1 ] text2[j- 1]因为当他们都是空集的时候最长子序列也是空集 13 | for(let i = 1; i <= text1.length; i++){ 14 | for(let j = 1; j <= text2.length; j++){ 15 | if(text1[i-1] == text2[j-1]){ //如果现在的text1[i - 1] == text2[j - 1] 16 | dp[i][j] = dp[i - 1][j-1] + 1; //那么在dp[i][j]这个位置的子序列长度就是 dp[i - 1][j-1] + 1 17 | }else{ 18 | dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]) 19 | } 20 | } 21 | } 22 | 23 | // console.log(dp) 24 | 25 | return dp[text1.length][text2.length] 26 | }; 27 | 28 | ``` 29 | 30 | ### 复杂度分析 31 | 32 | 时间复杂度:O(M*N) 33 | 空间复杂度:O(M*N) 34 | -------------------------------------------------------------------------------- /leetcodepp3/DynamicProgramming/LC139.md: -------------------------------------------------------------------------------- 1 | ## LC 139 2 | 3 | ### 思路 4 | 5 | 动态规划 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var wordBreak = function(s, wordDict) { 11 | let dp = new Array(s.length); 12 | dp[0] = true; //寻常关系,也就是recursion的出循环点 13 | for(let i = 0; i <= s.length; i++){ //因为填写的dp[i]的范围到s.length 14 | for(word of wordDict){ 15 | if(word.length <= i && dp[i - word.length] == true && s.slice(i - word.length, i) === word){ // s'是s的substring,然后dp[i]表示s.slice(0,i) 是否能由字典里的词构成 16 | dp[i] = true; 17 | } 18 | } 19 | } 20 | // console.log(dp) 21 | return dp[s.length] || false; 22 | }; 23 | 24 | ``` 25 | 26 | ### 复杂度分析 27 | 28 | 时间复杂度:O(S^3) 29 | 空间复杂度:O(S + Dictionary.length) 30 | -------------------------------------------------------------------------------- /leetcodepp3/DynamicProgramming/LC300.md: -------------------------------------------------------------------------------- 1 | ## LC 300 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```JavaScript 8 | var lengthOfLIS = function(nums) { 9 | if(nums.length < 2) return nums.length; 10 | 11 | let dp = new Array(nums.length).fill(1); 12 | 13 | for(let i = 1; i < nums.length; i++){ 14 | for(let j = 0; j < i; j++){ 15 | if(nums[j] < nums[i]){ 16 | dp[i] = Math.max(dp[i], dp[j] + 1) 17 | } 18 | } 19 | } 20 | 21 | return Math.max(...dp); 22 | }; 23 | ``` 24 | 25 | ### 复杂度分析 26 | 27 | 时间复杂度:O(N^2) double for loop 28 | 空间复杂度:O(N) dp, same length as input 29 | -------------------------------------------------------------------------------- /leetcodepp3/DynamicProgramming/LC518.md: -------------------------------------------------------------------------------- 1 | ## LC 581 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```JavaScript 8 | var change = function(amount, coins) { 9 | const dp = new Array(amount+1).fill(0); 10 | //dp[amount现在的数量] = 可以组成这个amount的组合个数,假设每个coin可以取无数次 11 | dp[0] = 1; // dp[数量为0] = 可以都不选(一个组合) 12 | 13 | for(let i = 0; i < coins.length; i++){ 14 | for(let j = 0; j <= amount; j++){ 15 | if(j >= coins[i]) dp[j] += dp[j - coins[i]] 16 | } 17 | } 18 | // console.log(dp) 19 | return dp[amount] 20 | }; 21 | 22 | 23 | ``` 24 | 25 | ### 复杂度分析 26 | 27 | 时间复杂度:O(amount \* coins.length) 28 | 空间复杂度:O(amount) 29 | -------------------------------------------------------------------------------- /leetcodepp3/DynamicProgramming/LC53.md: -------------------------------------------------------------------------------- 1 | ## LC 53 2 | 3 | https://leetcode-cn.com/problems/maximum-subarray/ 4 | 5 | ### 思路 6 | 7 | 动态规划 8 | 9 | 动态方程:dp[i] = Math.max(dp[i-1] + nums[i], nums[i]) 10 | 11 | ### 代码 12 | 13 | ```JavaScript 14 | /** 15 | * @param {number[]} nums 16 | * @return {number} 17 | */ 18 | var maxSubArray = function(nums) { 19 | let pre = 0; let maxAns = nums[0]; 20 | 21 | for(let i = 0; i < nums.length; i++){ 22 | pre = Math.max(pre + nums[i], nums[i]); 23 | 24 | maxAns = Math.max(maxAns, pre); 25 | // console.log(`the ${i} loop with pre: ${pre} and maxAns: ${maxAns}`) 26 | } 27 | return maxAns 28 | }; 29 | 30 | ``` 31 | 32 | ### 复杂度分析 33 | 34 | 时间复杂度:O(N) 遍历一次 35 | 空间复杂度:O(1) 只存储了常量 36 | -------------------------------------------------------------------------------- /leetcodepp3/DynamicProgramming/LC62.md: -------------------------------------------------------------------------------- 1 | ## LC 62 2 | 3 | ### 思路 4 | 5 | dp 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var uniquePaths = function(m, n) { 11 | const dp = Array.from({length: m}).map(() => Array.from({length: n})); 12 | dp[0][0] = 0; 13 | for (let i = 0; i < m; i++) { 14 | dp[i][0] = 1; //因为单向性 15 | } 16 | for (let j = 0; j < n; j++) { 17 | dp[0][j] = 1; //因为单向性 18 | } 19 | //每次移动都是+1,所以不用visited={}来判断 20 | //dp[m][n] = # of ways 21 | for(let i = 1; i < m; i++){ 22 | for(let j = 1; j < n; j++){ 23 | dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 24 | } 25 | } 26 | 27 | return dp[m-1][n-1] 28 | }; 29 | 30 | ``` 31 | 32 | ### 复杂度分析 33 | 34 | 时间复杂度:O(M*N) 35 | 空间复杂度:O(M*N) 36 | -------------------------------------------------------------------------------- /leetcodepp3/DynamicProgramming/MinSubSeq.md: -------------------------------------------------------------------------------- 1 | ## 2 | 3 | https://binarysearch.com/problems/Minimum-Sum-Subsequence 4 | 5 | ### 思路 6 | 7 | 爬楼梯换皮 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | class Solution { 13 | solve(nums) { 14 | if(nums.length <= 3) return Math.min(...nums) 15 | const dp = new Array(nums.length).fill(0); 16 | dp[0] = nums[0]; 17 | dp[1] = nums[1]; 18 | dp[2] = nums[2]; 19 | for(let i = 3; i < nums.length; i++){ 20 | dp[i] = Math.min(dp[i-3], dp[i-2], dp[i-1]) + nums[i] 21 | } 22 | // console.log(dp) 23 | return Math.min(dp[dp.length - 1],dp[dp.length - 2], dp[dp.length - 3] ) 24 | } 25 | } 26 | 27 | ``` 28 | 29 | ### 复杂度分析 30 | 31 | 时间复杂度:O(N) 32 | 空间复杂度:O(N) 33 | -------------------------------------------------------------------------------- /leetcodepp3/Greedy/LC435.md: -------------------------------------------------------------------------------- 1 | ## LC 435. Non-overlapping Intervals 2 | 3 | ### 思路 4 | 5 | 贪心 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | 11 | /** 12 | * @param {number[][]} intervals 13 | * @return {number} 14 | */ 15 | var eraseOverlapIntervals = function(intervals) { 16 | let stack = []; 17 | let result = 0; 18 | intervals = intervals.sort((a,b) => a[1] - b[1]) 19 | for(let ele of intervals){ 20 | if(stack.length == 0){ 21 | stack.push(ele[0],ele[1]) 22 | }else{ 23 | if(ele[0] >= stack[stack.length - 1]){ 24 | stack.push(ele[0],ele[1]) 25 | }else{ 26 | result++; 27 | } 28 | } 29 | } 30 | return result; 31 | }; 32 | ``` 33 | 34 | ### 复杂度分析 35 | 36 | 时间复杂度:N(nlogN) 37 | 空间复杂度:O(N) 38 | -------------------------------------------------------------------------------- /leetcodepp3/Greedy/LC455.md: -------------------------------------------------------------------------------- 1 | ## LC 455. Assign Cookies 2 | 3 | https://leetcode-cn.com/problems/assign-cookies/ 4 | 5 | ### 思路 6 | 7 | 贪心 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | /** 13 | * @param {number[]} g 14 | * @param {number[]} s 15 | * @return {number} 16 | */ 17 | var findContentChildren = function(g, s) { 18 | g = g.sort((a,b) => a-b) 19 | s = s.sort((a,b) => a-b) 20 | let j = g.length - 1, i = s.length - 1; 21 | let result =0 22 | while((j >= 0) && i >= 0){ 23 | // console.log(j,i) 24 | if(s[i] >= g[j]){ 25 | result++; 26 | i--; 27 | j--; 28 | }else{ 29 | j--; 30 | } 31 | } 32 | 33 | return result; 34 | }; 35 | 36 | ``` 37 | 38 | ### 复杂度分析 39 | 40 | 时间复杂度:O(nlogM + nlogN) M 和 n 分别是数组长度,时间花费在 sort 和遍历 41 | 空间复杂度:O(1) 42 | -------------------------------------------------------------------------------- /leetcodepp3/Greedy/LC881.md: -------------------------------------------------------------------------------- 1 | ## LC 881 2 | 3 | ### 思路 4 | 5 | 如果胖的和瘦的不能一起装下,就只装胖的 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | 11 | var numRescueBoats = function(people, limit) { 12 | people.sort((a, b) => a - b) 13 | 14 | let ans = 0, start = 0, end = people.length - 1; 15 | 16 | while (start <= end) { 17 | if (people[end] + people[start] <= limit){ 18 | start++; 19 | end--; 20 | } else { 21 | end--; 22 | } 23 | ans++; 24 | } 25 | return ans; 26 | }; 27 | ``` 28 | 29 | ### 复杂度分析 30 | 31 | 时间复杂度:O(nlogn) 32 | 空间复杂度:O(1) 33 | -------------------------------------------------------------------------------- /leetcodepp3/Heap/Quicksort.md: -------------------------------------------------------------------------------- 1 | ## LC 2 | 3 | ### 思路 4 | 5 | ### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var quickSort = function(arr){ 9 | if(arr.length <= 1) return arr; 10 | 11 | let pivot = arr[0]; 12 | let left = [], right = []; 13 | 14 | for(let i = 1; i < arr.length; i++){ 15 | if(arr[i]> pivot){ 16 | right.push(arr[i]); 17 | }else{ 18 | left.push(arr[i]); 19 | } 20 | } 21 | 22 | return quickSort(left).concat([pivot]).concat(quickSort(right)); 23 | 24 | } 25 | 26 | console.log(quickSort([5,4,3,2,1,10,7])) 27 | 28 | ``` 29 | 30 | ### 复杂度分析 31 | 32 | 时间复杂度: 33 | 空间复杂度: 34 | -------------------------------------------------------------------------------- /leetcodepp3/LinkedList/D9 LC109.md: -------------------------------------------------------------------------------- 1 | ## LC 109 2 | https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/ 3 | ### 思路 4 | 快慢指针 5 | 6 | ### 代码 7 | ``` JavaScript 8 | var sortedListToBST = function(head) { 9 | if(head == null) return head; 10 | 11 | let slow = head, fast = head; 12 | let preSlow; 13 | 14 | while(fast && fast.next){ 15 | preSlow = slow; 16 | fast = fast.next.next; 17 | slow = slow.next; 18 | } 19 | 20 | const root = new TreeNode(slow.val); 21 | 22 | if(preSlow != null){ 23 | console.log("preSlow: ",preSlow) 24 | preSlow.next = null; 25 | root.left = sortedListToBST(head); 26 | } 27 | root.right = sortedListToBST(slow.next); 28 | 29 | return root; 30 | 31 | ``` 32 | ### 复杂度分析 33 | 时间复杂度:O(N)(log(N)) 34 | 空间复杂度:O(N)(log(N)) -------------------------------------------------------------------------------- /leetcodepp3/README.md: -------------------------------------------------------------------------------- 1 | ## Leetcode Plus Plus 力扣加加 2 | 3 | [力扣加加网站](https://leetcode-solution.cn/) 4 | 力扣加加也有微信公众号,可搜同名 5 | 6 | #### 91 算法(第三期) 7 | 8 | [91 算法第四期网站](https://algo91.herokuapp.com/91) 9 | 91 算法是一个为期 91 天的大家一起打卡的活动 10 | 大家可以一起做和学习带有讲解和按照专题的算法题 11 | 第三期已经结束,如果想关注可以戳官网或者第四期的网站 12 | 13 | 语言主要是 JavaScript... 14 | 中英文都有 15 | Lanaguages used: mostly JavaScript 16 | Langguages for notes: English, Chinese 17 | -------------------------------------------------------------------------------- /leetcodepp3/Search&BackTrack/LC46.md: -------------------------------------------------------------------------------- 1 | ## LC 46 2 | 3 | ### 思路 4 | 5 | 回溯 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var permute = function(nums) { 11 | var backTrack = function(result, nums, tempList){ 12 | if(tempList.length == nums.length) return result.push([...tempList]); 13 | for(let i = 0; i < nums.length; i++ ){ 14 | if(tempList.includes(nums[i])) continue; //保证不重复 15 | tempList.push(nums[i]); 16 | backTrack(result, nums, tempList); 17 | tempList.pop(); 18 | } 19 | } 20 | 21 | const result = []; 22 | backTrack(result, nums, []); 23 | return result; 24 | }; 25 | 26 | ``` 27 | 28 | ### 复杂度分析 29 | 30 | 时间复杂度: 31 | 空间复杂度: 32 | -------------------------------------------------------------------------------- /leetcodepp3/Search&BackTrack/LC47.md: -------------------------------------------------------------------------------- 1 | ## LC 47 2 | 3 | ### 思路 4 | 5 | 回溯 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var permuteUnique = function(nums) { 11 | 12 | var backtrack = function(result, nums, tempList, visited){ 13 | if(tempList.length === nums.length){ 14 | return result.push([...tempList]); 15 | } 16 | 17 | // console.log(nums) 18 | 19 | for(let i = 0; i < nums.length; i++){ 20 | if(visited[i]) continue; 21 | if(i != 0 && nums[i] == nums[i -1] && visited[i - 1] ) continue; //用visited来记录是否记录过这个数字,JS是dynamic array 22 | tempList.push(nums[i]); 23 | visited[i] = true; 24 | backtrack(result, nums, tempList, visited); 25 | visited[i] = false; 26 | tempList.pop(); 27 | } 28 | } 29 | 30 | const result = []; 31 | backtrack(result,nums.sort((a,b) => a-b),[],[]) 32 | return result; 33 | }; 34 | 35 | ``` 36 | 37 | ### 复杂度分析 38 | 39 | 时间复杂度: 40 | 空间复杂度: 41 | -------------------------------------------------------------------------------- /leetcodepp3/Search&BackTrack/LC78.md: -------------------------------------------------------------------------------- 1 | ## LC 78 2 | 3 | ### 思路 4 | 5 | 回溯 6 | 7 | ### 代码 8 | 9 | ```JavaScript 10 | var subsets = function(nums) { 11 | 12 | var backTrack = function(tempList, nums, result, startIndex){ 13 | result.push([...tempList]); 14 | for(let i = startIndex; i < nums.length; i++){ 15 | tempList.push(nums[i]); 16 | backTrack(tempList,nums,result, i + 1); 17 | tempList.pop(); 18 | } 19 | } 20 | 21 | const result = []; 22 | backTrack([],nums,result, 0) 23 | return result; 24 | }; 25 | 26 | ``` 27 | 28 | ### 复杂度分析 29 | 30 | 时间复杂度: 31 | 空间复杂度: 32 | -------------------------------------------------------------------------------- /leetcodepp3/Search&BackTrack/LC90.md: -------------------------------------------------------------------------------- 1 | ## LC 90 2 | 3 | https://leetcode-cn.com/problems/subsets-ii/ 4 | 5 | ### 思路 6 | 7 | 回溯 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | 13 | var subsetsWithDup = function(nums) { 14 | 15 | var backTrack = function(nums, result, tempList, startIndex){ 16 | result.push([...tempList]); //copy instead of re-referencing 17 | for(let i = startIndex; i < nums.length; i++){ 18 | if( i != startIndex && nums[i] == nums[i - 1]) continue; // the input array has to be sorted so this would work 19 | tempList.push(nums[i]); 20 | backTrack(nums,result,tempList, i + 1); 21 | tempList.pop(); 22 | } 23 | } 24 | const result = []; 25 | backTrack(nums.sort((a,b) => a-b), result, [], 0); 26 | return result; 27 | }; 28 | ``` 29 | 30 | ### 复杂度分析 31 | 32 | 时间复杂度: 33 | 空间复杂度: 34 | -------------------------------------------------------------------------------- /leetcodepp3/SlidingWindow/D35 LC1456.md: -------------------------------------------------------------------------------- 1 | ## LC 1456 2 | 3 | https://leetcode-cn.com/problems/maximum-number-of-vowels-in-a-substring-of-given-length/ 4 | 5 | ### 思路 6 | 7 | 套用西法的模板就好了 8 | 先构建窗口 9 | 然后以固定窗口大小 k 滑动窗口,在滑动的同时检测是否需要改变现状的值并且更新结果 10 | 11 | ### 代码 12 | 13 | ```JavaScript 14 | var maxVowels = function(s, k) { 15 | const dic = new Set(['a','e','i','o','u']); 16 | let result = 0; 17 | let i = 0; 18 | while(i < k){ 19 | if(dic.has(s[i])){ 20 | result++; 21 | } 22 | i++; 23 | } 24 | 25 | let l = 1, r = k ; 26 | let current = result; 27 | while(r < s.length){ 28 | if(dic.has(s[r])) current++; 29 | if(dic.has(s[l-1])) current--; 30 | 31 | result = Math.max(result, current); 32 | r++; 33 | l++; 34 | } 35 | 36 | return result; 37 | }; 38 | 39 | ``` 40 | 41 | ### 复杂度分析 42 | 43 | 时间复杂度:O(N _ R)遍历一次 _ 每次读取 s[i]的时间 四舍五入就是...O(N)? 44 | 空间复杂度:O(1)只有常量 45 | -------------------------------------------------------------------------------- /leetcodepp3/SlidingWindow/LC1838.md: -------------------------------------------------------------------------------- 1 | ## LC 1838 2 | 3 | https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/ 4 | 5 | ### 思路 6 | 7 | 滑动窗口 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | var maxFrequency = function(nums, k) { 13 | nums = nums.sort((a,b) => a-b) 14 | 15 | let ans = 1; 16 | let j = 0; 17 | let a = 0; 18 | for(let i = 1; i < nums.length; i++){ 19 | a += (nums[i] - nums[i - 1]) * (i - j); //[1,2,4]举例: i=1 的时候已经是 [2,2]了所以 i=2 的时候只要现在的方程就好了 20 | while(a > k){ 21 | a -= nums[i] - nums[j]; 22 | j++; 23 | } 24 | ans = Math.max(i - j + 1, ans); //frequency = 长度 25 | } 26 | return ans; 27 | 28 | }; 29 | 30 | ``` 31 | 32 | ### 复杂度分析 33 | 34 | 时间复杂度:O(NlogN) 35 | 空间复杂度:O(logN) 排序数组需要使用的栈的空间 36 | -------------------------------------------------------------------------------- /leetcodepp3/TwoPointers/D25 LC867.md: -------------------------------------------------------------------------------- 1 | ## LC 867 2 | 3 | https://leetcode-cn.com/problems/middle-of-the-linked-list/ 4 | 5 | ### 思路 6 | 7 | 快慢指针 8 | 要注意表长是单数和双数的时候的区别 9 | 10 | ### 代码 11 | 12 | ```JavaScript 13 | var middleNode = function(head) { 14 | let fast = head, slow = head; 15 | 16 | while(fast && fast.next){ 17 | fast = fast.next.next; 18 | slow = slow.next; 19 | } 20 | return slow; 21 | }; 22 | 23 | ``` 24 | 25 | ### 复杂度分析 26 | 27 | 时间复杂度:O(N) 遍历一次 28 | 空间复杂度:O(1) 只有常量 29 | -------------------------------------------------------------------------------- /leetcodepp3/TwoPointers/D26 LC26.md: -------------------------------------------------------------------------------- 1 | ## LC 26 2 | 3 | https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/ 4 | 5 | ### 思路 6 | 7 | 双指针,如果是遇到快慢指针相同的情况,就让快指针再走一步 8 | 如果遇到快慢指针不同的情况,就让慢指针走一步且在此位置更新值 9 | 10 | ### 代码 11 | 12 | ```JavaScript 13 | var removeDuplicates = function(nums) { 14 | if(nums.length <= 1) return nums; 15 | let fast = 1, slow = 0; 16 | 17 | while(fast < nums.length){ 18 | if(nums[fast] != nums[slow]){ 19 | slow++; 20 | nums[slow] = nums[fast]; 21 | } 22 | fast++; 23 | } 24 | return slow+1; 25 | }; 26 | 27 | ``` 28 | 29 | ### 复杂度分析 30 | 31 | 时间复杂度:O(N) 遍历一遍 32 | 空间复杂度:O(1) 只存储常量 33 | -------------------------------------------------------------------------------- /leetcodepp3/TwoPointers/D27 LC35.md: -------------------------------------------------------------------------------- 1 | ## LC 35 2 | 3 | https://leetcode-cn.com/problems/search-insert-position/ 4 | 5 | ### 思路 6 | 7 | 二分法 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | var searchInsert = function(nums, target) { 13 | let left = 0, right = nums.length - 1, result = nums.length; 14 | 15 | while(left <= right){ 16 | let mid = ((right - left) >> 1) + left; 17 | if(target <= nums[mid]){ 18 | result = mid; 19 | right = mid - 1; 20 | }else{ 21 | left = mid + 1; 22 | } 23 | } 24 | 25 | return result; 26 | }; 27 | 28 | ``` 29 | 30 | ### 复杂度分析 31 | 32 | 时间复杂度:O(NlogN) 33 | 空间复杂度:O(1) 34 | -------------------------------------------------------------------------------- /leetcodepp3/hashtable/D19 LC1.md: -------------------------------------------------------------------------------- 1 | ## LC 1 2 | 3 | ### 思路 4 | 5 | 哈希表 6 | 遍历,检查哈希表中是否存在自己想要的数值 7 | 如果有,那么返回现在的 index 和哈希表中的对应 value 8 | 如果没有,哈希表存储格式是 数值 - index 9 | 因为说了每个题目有唯一正确答案,所以不考虑没有答案的情况 10 | 11 | index 的翻译是什么 角标吗?那上标和下标又是啥子呢? 12 | 13 | 话不多说 14 | 都是老朋友了 15 | 16 | ### 代码 17 | 18 | ```JavaScript 19 | var twoSum = function(nums, target) { 20 | let memo = new Map(); 21 | for(let i = 0; i < nums.length; i++){ 22 | if(memo.has(target-nums[i])){ 23 | return Array(memo.get(target-nums[i]), i) 24 | }else{ 25 | memo.set(nums[i],i) 26 | } 27 | } 28 | }; 29 | 30 | ``` 31 | 32 | ### 复杂度分析 33 | 34 | 时间复杂度:O(N) N 是 nums 的长度,因为要遍历 35 | 空间复杂度:O(N) 最坏情况下要存储 N 个数值在 map 中 36 | -------------------------------------------------------------------------------- /leetcodepp3/hashtable/D20 LC347.md: -------------------------------------------------------------------------------- 1 | ## LC 347 2 | 3 | https://leetcode-cn.com/problems/top-k-frequent-elements/ 4 | 5 | ### 思路 6 | 7 | 遍历一次,统计每个元素出现的次数,并且以 元素-次数的方式存入 map 中 8 | 然后根据次数排序 9 | 然后截取需要的个数 10 | 然后返回元素们 11 | 12 | ### 代码 13 | 14 | ```JavaScript 15 | /** 16 | * @param {number[]} nums 17 | * @param {number} k 18 | * @return {number[]} 19 | */ 20 | var topKFrequent = function(nums, k) { 21 | let memo = new Map(); 22 | 23 | for(let i = 0; i < nums.length; i++){ 24 | memo.has(nums[i]) ? memo.set(nums[i], memo.get(nums[i]) + 1) : memo.set(nums[i],1) 25 | } 26 | 27 | 28 | return [...memo.entries()].sort((a,b) => b[1] - a[1]).slice(0,k).map((a) => a[0]); 29 | }; 30 | 31 | ``` 32 | 33 | ### 复杂度分析 34 | 35 | 时间复杂度:O(N) 36 | 空间复杂度:O(N) 37 | -------------------------------------------------------------------------------- /leetcodepp3/剪枝/LC814. Binary Tree Pruning.md: -------------------------------------------------------------------------------- 1 | ## LC814. Binary Tree Pruning 2 | 3 | https://leetcode-cn.com/problems/binary-tree-pruning/ 4 | 5 | ### 思路 6 | 7 | ### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var pruneTree = function(root) { 11 | 12 | if(!root ) return null; 13 | 14 | root.left = pruneTree(root.left) 15 | root.right = pruneTree(root.right) 16 | if(root.left == null && root.right == null && root.val == 0) return null; 17 | 18 | return root 19 | }; 20 | ``` 21 | 22 | ### 复杂度分析 23 | 24 | 时间复杂度: O(N) N 为 node 的个数 25 | 空间复杂度: O(H) H 为树的高度 26 | -------------------------------------------------------------------------------- /leetcodepp3/高频题/D86 位运算.md: -------------------------------------------------------------------------------- 1 | # 位运算 2 | 3 | - 位运算 4 | - [LC 136 Single Number](#LC-136.-Single-Number) 5 | 6 | ## LC 136. Single Number 7 | 8 | ### 思路 9 | 10 | 位运算 11 | 因为 12 | a ^ 0 = a 13 | a ^ a = 0 14 | 且位运算满足交换和结合律 15 | 16 | ### 代码 JavaScript 17 | 18 | ```JavaScript 19 | var singleNumber = function(nums) { 20 | let ans = 0; 21 | 22 | for(num of nums){ 23 | ans ^= num 24 | } 25 | 26 | return ans; 27 | }; 28 | 29 | ``` 30 | 31 | ### 复杂度分析 32 | 33 | 时间复杂度:O(N)
34 | 空间复杂度:O(1) 35 | -------------------------------------------------------------------------------- /leetcodepp4/D10 LC 160. Intersection of Two Linked Lists.md: -------------------------------------------------------------------------------- 1 | ## LC 160. Intersection of Two Linked Lists 2 | 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var getIntersectionNode = function(headA, headB) { 11 | // a + c + b === b + c + a 12 | 13 | //for intersect LinkedLists, a == b at the intersect point 14 | //for no-intersect LinkedLists, a == b at null 15 | let a = headA, b = headB 16 | while(a != b){ 17 | a = a ? a.next : headB 18 | b = b ? b.next : headA 19 | } 20 | 21 | return a; 22 | }; 23 | 24 | ``` 25 | 26 | #### 复杂度分析 27 | 28 | 时间复杂度:O(M+N) MN 分别是 LinkedList A 和 B 的长度
29 | 空间复杂度:O(1) 30 | -------------------------------------------------------------------------------- /leetcodepp4/D25 LC876. Middle of the Linked List.md: -------------------------------------------------------------------------------- 1 | ## LC 876. Middle of the Linked List 2 | 3 | https://leetcode-cn.com/problems/middle-of-the-linked-list/ 4 | 5 | - [双指针](#思路-双指针) 6 | 7 | ### 思路 双指针 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var middleNode = function(head) { 13 | let slow = head, fast = head; 14 | 15 | while(fast && fast.next){ 16 | fast = fast.next.next 17 | slow = slow.next 18 | } 19 | 20 | return slow 21 | }; 22 | 23 | ``` 24 | 25 | #### 复杂度分析 26 | 27 | 时间复杂度:O(N)
28 | 空间复杂度:O(1) 29 | -------------------------------------------------------------------------------- /leetcodepp4/D26 LC26. Remove Duplicates from Sorted Array.md: -------------------------------------------------------------------------------- 1 | ## LC 26. Remove Duplicates from Sorted Array 2 | 3 | ### 思路 双指针 4 | 5 | LC80 的妹妹 6 | 原地修改已经排序的数组,我们需要知道: 1)需要保留的值 : slow - 1 2)需要被修改的位置 : slow 7 | 3)2 中需要修改成什么值 : fast 8 | 9 | 1. 当 slow< 1 的时候 slow 向前走,因为数组里的第一个肯定是要保留的; 10 | 2. 当 slow >= 1 的时候,slow 来到了可能需要被修改的位置 11 | 2.1 如果需要保留的值和 fast 是一样的,说明此处有重复,但 fast 并不是我们要找的值,所以 fast++, slow 不动 12 | 2.2 如果需要保留的值 和 fast 是不一样的,说明此时应该 nums[slow] = nums[fast] 并且 slow 继续往前走 13 | 14 | (换句话说 slow 一直处在可能需要被修改的地方) 15 | 16 | #### 代码 JavaScript 17 | 18 | ```JavaScript 19 | var removeDuplicates = function(nums) { 20 | let slow = 0 21 | 22 | for(let fast = 0; fast < nums.length; fast++){ 23 | if(slow < 1 || nums[slow-1] != nums[fast]){ 24 | nums[slow] = nums[fast] 25 | slow++ 26 | } 27 | } 28 | 29 | return slow 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 36 | 时间复杂度:O(N)
37 | 空间复杂度:O(1) 38 | -------------------------------------------------------------------------------- /leetcodepp4/D27 LC35. Search Insert Position.md: -------------------------------------------------------------------------------- 1 | ## LC 35. Search Insert Position 2 | 3 | https://leetcode-cn.com/problems/search-insert-position/ 4 | 5 | - [二分搜索](#思路-二分搜索) 6 | 7 | ### 思路 二分搜索 8 | 9 | 二分搜索-寻找最左插入位置 10 | 11 | #### 代码 JavaScript 12 | 13 | ```JavaScript 14 | var searchInsert = function(nums, target) { 15 | let left = 0, right = nums.length - 1 16 | 17 | while(left <= right){ 18 | const mid = left + ((right - left) >> 1) 19 | 20 | if(target == nums[mid]){ 21 | right = mid - 1 22 | }else if(target > nums[mid]){ 23 | left = mid + 1 24 | }else{ 25 | right = mid - 1 26 | } 27 | } 28 | 29 | return left; 30 | }; 31 | 32 | ``` 33 | 34 | #### 复杂度分析 35 | 36 | 时间复杂度:O(logN)
37 | 空间复杂度:O(1) 38 | -------------------------------------------------------------------------------- /leetcodepp4/D29 LC69. Sqrt(x).md: -------------------------------------------------------------------------------- 1 | ## LC 69. Sqrt(x) 2 | https://leetcode-cn.com/problems/sqrtx/ 3 | 4 | ### 思路 二分法 5 | 等价于在有限的解空间[1..x]内,用二分法寻找某个数,这个 ans ** 2 刚好小于x。 6 | 7 | 也就是等价于在这个解空间内用二分法查找最左插入点。 8 | 复习一下最左插入点 9 | ```JavaScript 10 | console.log(bleft([1, 2, 3, 3, 3, 4, 5, 6], 3)) => 2 11 | console.log(bleft([1, 2, 3, 3, 3, 4, 5, 6], 2)) => 1 12 | console.log(bleft([1, 2, 3, 3, 3, 4, 5, 6], 4)) => 5 13 | ``` 14 | 15 | #### 代码 JavaScript 16 | 17 | ```JavaScript 18 | var mySqrt = function(x) { 19 | 20 | let left = 1, right = x 21 | 22 | while(left <= right){ 23 | const mid = left + ((right - left) >> 1) 24 | const midSqr = mid ** 2 25 | if(midSqr > x) right = mid - 1 26 | if(midSqr == x) right = mid - 1 27 | if(midSqr < x) left = mid + 1 28 | } 29 | 30 | return left ** 2 == x ? left : left - 1 31 | }; 32 | 33 | ``` 34 | 35 | #### 复杂度分析 36 | 37 | 时间复杂度:logN
38 | 空间复杂度:O(1) 39 | -------------------------------------------------------------------------------- /leetcodepp4/D35 LC1456. Maximum Number of Vowels in a Substring of Given Length.md: -------------------------------------------------------------------------------- 1 | ## LC 1456. Maximum Number of Vowels in a Substring of Given Length 2 | https://leetcode-cn.com/problems/maximum-number-of-vowels-in-a-substring-of-given-length/ 3 | - [哈希表+固定大小的滑动窗口](#思路-哈希表+固定大小的滑动窗口) 4 | 5 | ### 思路 哈希表+固定大小的滑动窗口 6 | 我这样写比较别扭的点在于要知道其实窗口的取值范围是[j+1..i] 7 | 但是还是把一开始建立窗口和后面滑动窗口的部分分开了,省的写那么多边界判断。 8 | hard我哭唧唧,mid我重拳出击! 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var maxVowels = function(s, k) { 13 | //固定滑动窗口 14 | const dict = new Set(['a', 'e', 'i', 'o', 'u']) 15 | let ret = 0 16 | for(let i = 0; i 35 | 空间复杂度:O(1) 36 | -------------------------------------------------------------------------------- /leetcodepp4/D45 Top View of a Tree.md: -------------------------------------------------------------------------------- 1 | ## Top View of a Tree 2 | 3 | https://binarysearch.com/problems/Top-View-of-a-Tree 4 | 5 | ### 思路 BFS 6 | BFS带参(哦我超级无敌喜欢带参... 7 | 只不过这次的参数是把root视为一个x轴,值为0;同时建立一个map来记录x坐标轴位置=>node。因为bfs的特性会先搜上面的层,所以如果某个坐标值被记录过了,就不用被更新了。 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | class Solution { 12 | solve(root) { 13 | if(!root) return [] 14 | const view = new Map 15 | view.set(0, root.val) 16 | const queue = [[root,0]] 17 | 18 | while(queue.length){ 19 | const [node, cor] = queue.shift() 20 | if(!view.has(cor)) view.set(cor, node.val) 21 | node.left && queue.push([node.left, cor -1]) 22 | node.right && queue.push([node.right, cor + 1]) 23 | } 24 | 25 | const res = [...view.entries()].sort((a,b) => a[0] -b[0]) 26 | return res.map(([k,v]) => v) 27 | } 28 | } 29 | 30 | ``` 31 | 32 | #### 复杂度分析 33 | 时间复杂度:O(NlogN)排序的大小 搜所有的点
34 | 空间复杂度:O(N) memo和queue的大小 -------------------------------------------------------------------------------- /leetcodepp4/D46 LC746. Min Cost Climbing Stairs.md: -------------------------------------------------------------------------------- 1 | ## LC 746. Min Cost Climbing Stairs 2 | https://leetcode-cn.com/problems/min-cost-climbing-stairs/ 3 | 4 | ### 思路 动态规划 5 | 首先可以看出来,这是一个由状态累加的题 -- 也就是说某个楼梯的花费依赖于前面的楼梯的花费; 6 | 然后可以看出来,当前爬楼梯的花费等于 `dp[i] = Math.min(dp[i-1], dp[i-2]) + cost[i]` 7 | 查看base case:`dp[0]` , `dp[1]`;明确需求:top 指的是 cost.length,且最后一步不花钱。 8 | 处理边界: `cost[i] || 0` 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | var minCostClimbingStairs = function(cost) { 13 | //dp[i] = min cost 14 | const dp = new Array(cost.length + 1).fill(Number.MAX_SAFE_INTEGER) 15 | 16 | dp[0] = cost[0] 17 | dp[1] = cost[1] 18 | 19 | for(let i = 2; i < dp.length; i++){ 20 | dp[i] = Math.min(dp[i-1], dp[i-2]) + (cost[i] || 0) 21 | } 22 | 23 | return dp[cost.length] 24 | }; 25 | 26 | ``` 27 | 28 | #### 复杂度分析 29 | 时间复杂度:O(n) 30 | 空间复杂度:O(n) -------------------------------------------------------------------------------- /leetcodepp4/D47 LC198. House Robber.md: -------------------------------------------------------------------------------- 1 | ## LC 198. House Robber 2 | https://leetcode-cn.com/problems/house-robber/ 3 | ### 思路 动态规划 4 | 为什么这道题想到用动态规划?因为这个大问题可以分割成无数个相同的子问题,这个大问题的最优解也是子问题的最优解,并且这个大问题的最优解是子问题的最优解的累计。 5 | 6 | 换句话说,在某个固定的input下,抢劫前5个房子的最优解跟抢劫前4个房子的最优解有递推的关系...以此类推。推到一个无论何时都能直接表示的关系的时候,就是base case。 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var rob = function(nums) { 11 | const n = nums.length 12 | const dp = new Array(n).fill(0) 13 | 14 | dp[0] = nums[0] 15 | 16 | for(let i = 1; i < n; i++){ 17 | dp[i] = Math.max(dp[i-1], (dp[i-2] || 0) + nums[i]) 18 | } 19 | 20 | return dp[n - 1] 21 | }; 22 | 23 | ``` 24 | 25 | #### 复杂度分析 26 | 时间复杂度:O(n) 27 | 空间复杂度:O(n) -------------------------------------------------------------------------------- /leetcodepp4/D49 LC1143. Longest Common Subsequence.md: -------------------------------------------------------------------------------- 1 | ## LC 1143. Longest Common Subsequence 2 | https://leetcode-cn.com/problems/longest-common-subsequence/ 3 | ### 思路 4 | 5 | #### 代码 JavaScript 6 | 7 | ```JavaScript 8 | var longestCommonSubsequence = function(text1, text2) { 9 | 10 | const dp = Array.from({length: text1.length + 1}).map(() => Array.from({length: text2.length + 1}).fill(0)) 11 | let ret = 0 12 | 13 | for(let i = 1; i <= text1.length; i++){ 14 | for(let j = 1; j <= text2.length; j++){ 15 | if(text1[i-1] == text2[j - 1]){ 16 | dp[i][j] = dp[i-1][j-1] + 1 17 | 18 | }else{ 19 | dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) 20 | } 21 | ret = Math.max(dp[i][j], ret) 22 | } 23 | } 24 | return ret 25 | }; 26 | 27 | ``` 28 | 29 | #### 复杂度分析 30 | 时间复杂度:O(mn)
31 | 空间复杂度:O(mn) -------------------------------------------------------------------------------- /leetcodepp4/D57 LC455. Assign Cookies.md: -------------------------------------------------------------------------------- 1 | ## LC 455. Assign Cookies 2 | https://leetcode-cn.com/problems/assign-cookies/ 3 | - [贪心](#思路-贪心) 4 | 5 | ### 思路 贪心 6 | 局部最优解就是全局最优解 7 | 我还特地看了一下tag,dp终于玩了吗呜呜呜 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | 12 | var findContentChildren = function(g, s) { 13 | if(s.length == 0) return 0 14 | let ans = 0 15 | 16 | s.sort((a,b) => a - b) 17 | g.sort((a,b) => a - b) 18 | for(let i = 0, j = 0; i < g.length && j < s.length; i++, j++){ 19 | while(j < s.length && g[i] > s[j]){ 20 | j++ 21 | } 22 | if( j < s.length){ 23 | ans++ 24 | } 25 | } 26 | 27 | return ans 28 | }; 29 | ``` 30 | 31 | #### 复杂度分析 32 | 时间复杂度:O(nlogn + mlogm) 33 | 空间复杂度:O(logn+logm) 排序时候使用的栈 -------------------------------------------------------------------------------- /leetcodepp4/D59 LC881. Boats to Save People.md: -------------------------------------------------------------------------------- 1 | ## LC 881. Boats to Save People 2 | https://leetcode-cn.com/problems/boats-to-save-people/ 3 | 4 | ### 思路 贪心 5 | 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var numRescueBoats = function(people, limit) { 10 | people.sort((a,b) => a - b) 11 | let ans = 0 12 | let l = 0, r = people.length - 1 13 | 14 | while(l <= r){ 15 | if(people[l] + people[r] <= limit) l++ 16 | r-- 17 | ans++ 18 | } 19 | return ans 20 | }; 21 | 22 | ``` 23 | #### 复杂度分析 24 | 时间复杂度:O(nlogn) 排序nlogn 遍历on 25 | 空间复杂度:O(logn) 排序 -------------------------------------------------------------------------------- /leetcodepp4/D62 LC932. Beautiful Array.md: -------------------------------------------------------------------------------- 1 | ## LC 932. Beautiful Array 2 | https://leetcode-cn.com/problems/beautiful-array/ 3 | 4 | ### 思路 divide and conqure 5 | 6 | #### 代码 JavaScript 7 | 8 | ```JavaScript 9 | var beautifulArray = function(n) { 10 | const memo = new Map 11 | 12 | const helper = (n) => { 13 | if(memo.has(n)) return memo.get(n); 14 | 15 | const ans = new Array(n); 16 | 17 | if(n === 1) ans[0] = 1; 18 | else{ 19 | let t = 0 20 | let l = helper(Math.ceil(n / 2)) //odds 21 | l.forEach((e) => ans[t++] = 2 * e - 1) 22 | let r = helper(n >> 1) // even 23 | r.forEach((e) => ans[t++] = 2 * e) 24 | } 25 | 26 | memo.set(n, ans) 27 | return ans 28 | } 29 | 30 | return helper(n) 31 | 32 | }; 33 | 34 | ``` 35 | 36 | #### 复杂度分析 37 | 时间复杂度:nlogn 38 | 空间复杂度:nlogn -------------------------------------------------------------------------------- /leetcodepp4/D70 LC814. Binary Tree Pruning.md: -------------------------------------------------------------------------------- 1 | ## LC 814. Binary Tree Pruning 2 | https://leetcode-cn.com/problems/binary-tree-pruning/ 3 | - [后序遍历](#思路-后序遍历) 4 | 5 | ### 思路 后序遍历 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var pruneTree = function(root) { 11 | if(!root) return null; 12 | 13 | root.left = pruneTree(root.left); 14 | root.right = pruneTree(root.right); 15 | 16 | if(!root.left && !root.right && root.val === 0) return null; 17 | 18 | return root 19 | }; 20 | 21 | ``` 22 | 23 | #### 复杂度分析 24 | 时间复杂度:O(N) N是树的大小 遍历了每个节点
25 | 空间复杂度:O(N) 栈的深度,最坏可能性是O(N),一般而言是O(logN) -------------------------------------------------------------------------------- /leetcodepp4/D71 LC39. Combination Sum.md: -------------------------------------------------------------------------------- 1 | ## LC 39. Combination Sum 2 | https://leetcode-cn.com/problems/combination-sum/ 3 | 4 | - [回溯剪枝](#思路-回溯剪枝) 5 | 6 | ### 思路 回溯剪枝 7 | 剪枝思路:对于每个candidates[i],有可以继续选,以及之后不考虑了两种状态。当cnadidates[i] === undefined,剪掉。 8 | 同理,因为target取值范围是 target >= 1,所以当target <= 0 的时候,开始剪枝或者return。 9 | 10 | #### 代码 JavaScript 11 | 12 | ```JavaScript 13 | var combinationSum = function(candidates, target) { 14 | const ret = []; 15 | const backTrack = (curIndex, remainTarget, cur) => { 16 | if(remainTarget <= 0 || curIndex >= candidates.length){ 17 | if(remainTarget == 0){ 18 | ret.push(cur.slice()) 19 | } 20 | return; 21 | } 22 | 23 | for(let i = curIndex; i < candidates.length; i++){ 24 | backTrack(i, remainTarget - candidates[i], cur.concat(candidates[i])) 25 | } 26 | } 27 | 28 | backTrack(0, target, []) 29 | return ret; 30 | }; 31 | 32 | ``` 33 | -------------------------------------------------------------------------------- /leetcodepp4/D72 LC47. Permutations II.md: -------------------------------------------------------------------------------- 1 | ## LC 47. Permutations II 2 | https://leetcode-cn.com/problems/permutations-ii/ 3 | 4 | ### 思路 回溯剪枝 5 | 我觉得这类题最好的方法就是画状态树,画出来树了啥都知道了。 6 | 状态树的框架讲义里有,具体画法如果不明白可以看高票题解。 7 | 今天又是元气满满的一天呢 ヾ(◍°∇°◍)ノ゙ 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var permuteUnique = function(nums) { 12 | const ret = []; 13 | const visited = new Set() 14 | const bt = (cur) => { 15 | console.log(cur) 16 | if(cur.length === nums.length){ 17 | ret.push(cur.slice()); 18 | return 19 | } 20 | 21 | for(let i = 0; i < nums.length; i++){ 22 | if(visited.has(i)) continue 23 | if(nums[i] === nums[i - 1] && !visited.has(i - 1)) continue 24 | visited.add(i) 25 | bt(cur.concat(nums[i])) 26 | visited.delete(i) 27 | } 28 | } 29 | bt([]) 30 | return ret; 31 | }; 32 | 33 | ``` -------------------------------------------------------------------------------- /leetcodepp4/D78 LC1046. Last Stone Weight.md: -------------------------------------------------------------------------------- 1 | ## LC 1046. Last Stone Weight 2 | https://leetcode-cn.com/problems/last-stone-weight/ 3 | 4 | ### 思路 优先队列 5 | 用大顶堆动态求极值,注意如果最后剩下两块石头并且重量相同那么应该return 0. 6 | 7 | 用了LC内置的JS priorityqueue接口。 8 | #### 代码 JavaScript 9 | 10 | ```JavaScript 11 | var lastStoneWeight = function(stones) { 12 | const pq = new MaxPriorityQueue() 13 | for(const stone of stones){ 14 | pq.enqueue(stone, stone) 15 | } 16 | 17 | while(!pq.isEmpty()){ 18 | let stone1 = pq.dequeue()['priority']; 19 | if(pq.isEmpty()) return stone1; 20 | let stone2 = pq.dequeue()['priority']; 21 | 22 | if(stone1 !== stone2){ 23 | let newStone = Math.abs(stone1 - stone2) 24 | pq.enqueue(newStone, newStone) 25 | } 26 | } 27 | 28 | return 0 29 | }; 30 | 31 | ``` 32 | 33 | #### 复杂度分析 34 | 时间复杂度:O(n) 35 | 空间复杂度:O(n) -------------------------------------------------------------------------------- /leetcodepp4/D9 LC160. Intersection of Two Linked Lists.md: -------------------------------------------------------------------------------- 1 | ## LC 160. Intersection of Two Linked Lists 2 | 3 | - [双指针](#思路-双指针) 4 | 5 | ### 思路 双指针 6 | 7 | #### 代码 JavaScript 8 | 9 | ```JavaScript 10 | var getIntersectionNode = function(headA, headB) { 11 | // a + c + b === b + c + a 12 | 13 | //for intersect LinkedLists, a == b at the intersect point 14 | //for no-intersect LinkedLists, a == b at null 15 | let a = headA, b = headB 16 | while(a != b){ 17 | a = a ? a.next : headB 18 | b = b ? b.next : headA 19 | } 20 | 21 | return a; 22 | }; 23 | 24 | ``` 25 | 26 | #### 复杂度分析 27 | 28 | 时间复杂度:O(M+N) MN 分别是 LinkedList A 和 B 的长度
29 | 空间复杂度:O(1) 30 | -------------------------------------------------------------------------------- /leetcodepp4/README.md: -------------------------------------------------------------------------------- 1 | ## Leetcode Plus Plus 力扣加加 2 | 3 | [力扣加加网站](https://leetcode-solution.cn/) 4 | 力扣加加也有微信公众号,可搜同名 5 | 6 | #### 91 算法(第四期) 7 | 8 | [91 算法第四期网站](https://algo91.herokuapp.com/91) 9 | 91 算法是一个为期 91 天的大家一起打卡的活动 10 | 大家可以一起做和学习带有讲解和按照专题的算法题 11 | 12 | 语言主要是 JavaScript... 13 | 中英文都有 14 | Lanaguages used: mostly JavaScript 15 | Langguages for notes: English, Chinese 16 | -------------------------------------------------------------------------------- /重点基础题/LC141. Linked List Cycle.md: -------------------------------------------------------------------------------- 1 | ## LC 141. Linked List Cycle 2 | 3 | ### 思路 4 | 5 | ### 代码 6 | 7 | ```JavaScript 8 | var hasCycle = function(head) { 9 | if(!head || !head.next || !head.next.next) return false; //注意特别的corner case 10 | let slow = head, fast = head.next.next; 11 | 12 | while(slow != fast){ 13 | if(!fast || !slow) return false; 14 | slow = slow.next; 15 | fast = fast.next ? fast.next.next : null //注意要判断fast.next 在这或者在18 16 | } 17 | // console.log(slow, fast) 18 | return slow == fast; 19 | }; 20 | 21 | ``` 22 | 23 | ### 复杂度分析 24 | 25 | 时间复杂度: 26 | 空间复杂度: 27 | -------------------------------------------------------------------------------- /重点基础题/LC206. Reverse Linked List.md: -------------------------------------------------------------------------------- 1 | ## LC 206 2 | 3 | https://leetcode-cn.com/problems/reverse-linked-list/ 4 | 5 | ### 思路 6 | 7 | 迭代 8 | 9 | ### 代码 10 | 11 | ```JavaScript 12 | var reverseList = function(head) { 13 | let pre = null, cur = head; 14 | 15 | while(cur){ 16 | let next = cur.next; 17 | cur.next = pre; 18 | pre = cur; 19 | cur = next; 20 | } 21 | 22 | return pre; 23 | }; 24 | 25 | ``` 26 | 27 | ### 复杂度分析 28 | 29 | 时间复杂度:O(N) 30 | 空间复杂度:O(1) 31 | 32 | ### 思路 33 | 34 | 递归 35 | 36 | ### 代码 37 | 38 | ```JavaScript 39 | var reverseList = function(head) { 40 | if(!head || !head.next) return head; 41 | 42 | let newHead = reverseList(head.next); 43 | head.next.next = head; 44 | head.next = null; 45 | 46 | return newHead; 47 | }; 48 | 49 | ``` 50 | 51 | ### 复杂度分析 52 | 53 | 时间复杂度:O(N) 54 | 空间复杂度:O(N) 55 | -------------------------------------------------------------------------------- /重点基础题/TODOLC208. Implement Trie (Prefix Tree).md: -------------------------------------------------------------------------------- 1 | ## LC 208. Implement Trie (Prefix Tree) 2 | 3 | https://leetcode-cn.com/problems/implement-trie-prefix-tree/ 4 | 5 | - [解法副标题](#思路-解法副标题) 6 | 7 | ### 思路 解法副标题 8 | 9 | #### 代码 JavaScript 10 | 11 | ```JavaScript 12 | 13 | 14 | ``` 15 | 16 | #### 复杂度分析 17 | 18 | 时间复杂度:
19 | 空间复杂度: 20 | --------------------------------------------------------------------------------