├── LICENSE ├── README.md └── intensive_study_guides └── 20231226_040350 ├── leetcode_intensive_day_000001.md ├── leetcode_intensive_day_000002.md ├── leetcode_intensive_day_000003.md ├── leetcode_intensive_day_000004.md ├── leetcode_intensive_day_000005.md ├── leetcode_intensive_day_000006.md ├── leetcode_intensive_day_000007.md ├── leetcode_intensive_day_000008.md ├── leetcode_intensive_day_000009.md ├── leetcode_intensive_day_000010.md ├── leetcode_intensive_day_000011.md ├── leetcode_intensive_day_000012.md ├── leetcode_intensive_day_000013.md ├── leetcode_intensive_day_000014.md ├── leetcode_intensive_day_000015.md ├── leetcode_intensive_day_000016.md ├── leetcode_intensive_day_000017.md ├── leetcode_intensive_day_000018.md ├── leetcode_intensive_day_000019.md ├── leetcode_intensive_day_000020.md ├── leetcode_intensive_day_000021.md ├── leetcode_intensive_day_000022.md ├── leetcode_intensive_day_000023.md ├── leetcode_intensive_day_000024.md ├── leetcode_intensive_day_000025.md ├── leetcode_intensive_day_000026.md ├── leetcode_intensive_day_000027.md ├── leetcode_intensive_day_000028.md ├── leetcode_intensive_day_000029.md ├── leetcode_intensive_day_000030.md ├── leetcode_intensive_day_000031.md ├── leetcode_intensive_day_000032.md ├── leetcode_intensive_day_000033.md ├── leetcode_intensive_day_000034.md ├── leetcode_intensive_day_000035.md ├── leetcode_intensive_day_000036.md ├── leetcode_intensive_day_000037.md ├── leetcode_intensive_day_000038.md ├── leetcode_intensive_day_000039.md ├── leetcode_intensive_day_000040.md ├── leetcode_intensive_day_000041.md ├── leetcode_intensive_day_000042.md ├── leetcode_intensive_day_000043.md ├── leetcode_intensive_day_000044.md ├── leetcode_intensive_day_000045.md ├── leetcode_intensive_day_000046.md ├── leetcode_intensive_day_000047.md ├── leetcode_intensive_day_000048.md ├── leetcode_intensive_day_000049.md ├── leetcode_intensive_day_000050.md ├── leetcode_intensive_day_000051.md ├── leetcode_intensive_day_000052.md ├── leetcode_intensive_day_000053.md ├── leetcode_intensive_day_000054.md ├── leetcode_intensive_day_000055.md ├── leetcode_intensive_day_000056.md ├── leetcode_intensive_day_000057.md ├── leetcode_intensive_day_000058.md ├── leetcode_intensive_day_000059.md ├── leetcode_intensive_day_000060.md └── leetcode_intensive_day_000061.md /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Leetcode Intensive tutorial and study guide 2 | We leveraged cutting-edge tools to create an efficient and effective study aid for LeetCode users. Here's an overview of our technical stack and how each component contributes to the guide: 3 | 4 | ## Technical Stack: 5 | - **llama-index** 6 | - Function: Enhances the filling of LeetCode questions through integration with OpenAI. 7 | - Usage: 8 | - Utilizes a low-cost embedding model to process large amounts of data. 9 | - Generates embedding vectors for each LeetCode question, providing a unique representation based on its content. 10 | - **NetworkX** 11 | - Function: Optimizes the study path for learners. 12 | - Usage: 13 | - Constructs a low-cost spanning tree to understand the relationships between different problems. 14 | - Implements a Depth-First Search (DFS) algorithm to plan an effective study order, helping users to progress logically through related topics. 15 | - **SciKit-Learn** 16 | - Function: Clusters LeetCode problems for tailored learning experiences. 17 | - Usage: 18 | - Applies machine learning algorithms to cluster knowledge based on the similarity of the embeddings. 19 | - Groups similar problems together, allowing users to focus on specific areas of study or difficulty levels. 20 | - **Pydantic** 21 | - Function: Transforms unstructured data into a structured format. 22 | - Usage: 23 | - Converts unstructured LeetCode problem data into structured JSON format. 24 | - Ensures data integrity and facilitates easier manipulation and retrieval of problem information. 25 | -------------------------------------------------------------------------------- /intensive_study_guides/20231226_040350/leetcode_intensive_day_000001.md: -------------------------------------------------------------------------------- 1 | 2 | # Leetcode Intensive Tutorial Day 1 3 | > [Difficulty Score: 10] 4 | 5 | > [Version: 20231226_040350] 6 | 7 | > [Including this day, you had studied : 7 leetcode problems] 8 | 9 | 10 | ## Courses overview of the day 11 | 12 | - 572 Subtree of Another Tree [Easy] 13 | - 100 Same Tree [Easy] 14 | - 250 Count Univalue Subtrees [Medium] 15 | - 98 Validate Binary Search Tree [Medium] 16 | - 101 Symmetric Tree [Easy] 17 | - 545 Boundary of Binary Tree [Medium] 18 | - 226 Invert Binary Tree [Easy] 19 | 20 | #### Step by step 21 | 22 | - [1. From 572 Subtree of Another Tree [Easy] to 100 Same Tree [Easy]](#1-from-572-subtree-of-another-tree-easy-to-100-same-tree-easy)) 23 | 24 | - [2. From 100 Same Tree [Easy] to 250 Count Univalue Subtrees [Medium]](#2-from-100-same-tree-easy-to-250-count-univalue-subtrees-medium)) 25 | 26 | - [3. From 100 Same Tree [Easy] to 98 Validate Binary Search Tree [Medium]](#3-from-100-same-tree-easy-to-98-validate-binary-search-tree-medium)) 27 | 28 | - [4. From 100 Same Tree [Easy] to 101 Symmetric Tree [Easy]](#4-from-100-same-tree-easy-to-101-symmetric-tree-easy)) 29 | 30 | - [5. From 100 Same Tree [Easy] to 545 Boundary of Binary Tree [Medium]](#5-from-100-same-tree-easy-to-545-boundary-of-binary-tree-medium)) 31 | 32 | - [6. From 100 Same Tree [Easy] to 226 Invert Binary Tree [Easy]](#6-from-100-same-tree-easy-to-226-invert-binary-tree-easy)) 33 | 34 | 35 | 36 | #### Summary 37 | 38 | 39 | - 572 Subtree of Another Tree : Given two binary trees, check if one tree is a subtree of another tree. 40 | - 545 Boundary of Binary Tree : The essence of the problem is to find the boundary values of a binary tree in the required order without duplicate nodes. 41 | - 101 Symmetric Tree : The essence of the problem is to determine if a binary tree is symmetric by comparing the values of nodes and the mirror reflection of their subtrees. 42 | - 98 Validate Binary Search Tree : The essence of this problem is to determine if a binary tree satisfies the properties of a binary search tree. 43 | - 226 Invert Binary Tree : Inverting a binary tree. 44 | - 250 Count Univalue Subtrees : Count the number of uni-value subtrees in a binary tree. 45 | - 100 Same Tree : Check if two binary trees are the same by comparing their nodes recursively. 46 | > Similarity Diameter of these problems: 0.6399 47 | 48 | 49 | --- 50 | # 1. From 572 Subtree of Another Tree [Easy] to 100 Same Tree [Easy] 51 | > Similarity Distance: 0.3645 52 | 53 | ### >> 572 Subtree of Another Tree [Easy] 54 | Given two binary trees, check if one tree is a subtree of another tree. 55 | ##### Sample input: 56 | [3,4,5,1,2,null,null,null,null,0] 57 | [4,1,2] 58 | ##### Sample output: 59 | true 60 | 61 | ##### Questions to ask to clarify requirements: 62 | 63 | - Can the trees be empty? 64 | - Can the trees have duplicate values? 65 | - What is the maximum number of nodes in the trees? 66 | 67 | ##### Optimal Python solution: 68 | ```python 69 | def isSubtree(s, t): 70 | if s is None: 71 | return False 72 | if isSameTree(s, t): 73 | return True 74 | return isSubtree(s.left, t) or isSubtree(s.right, t) 75 | 76 | def isSameTree(p, q): 77 | if p is None and q is None: 78 | return True 79 | if p is None or q is None: 80 | return False 81 | return p.val == q.val and isSameTree(p.left, q.left) and isSameTree(p.right, q.right) 82 | ``` 83 | ##### Time complexity: 84 | O(m * n) 85 | ##### Space complexity: 86 | O(n) 87 | ##### Notes: 88 | 89 | - Check if the trees are the same 90 | - Recursively check if the left and right subtrees of the larger tree are the same as the smaller tree 91 | 92 | - Use recursion to check if the trees are the same. 93 | - Handle the case when the trees are empty by returning False. 94 | - Optimize the solution by checking if the trees are the same before recursively checking the subtrees. 95 | 96 | - Handling the case when the trees are empty 97 | 98 | - Using a brute force approach to check if the trees are the same 99 | 100 | ### >> 100 Same Tree [Easy] 101 | Given two binary trees, write a function to check if they are the same or not. 102 | ##### Sample input: 103 | 104 | - [1,2,3] 105 | - [1,2,3] 106 | ##### Sample output: 107 | 108 | - true 109 | 110 | ##### Questions to ask to clarify requirements: 111 | 112 | - Can we assume that the trees are binary trees? 113 | - Can we modify the trees? 114 | - Can we use extra space? 115 | 116 | ##### Optimal Python solution: 117 | ```python 118 | 119 | - class Solution: 120 | - def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: 121 | - if not p and not q: 122 | - return True 123 | - if not p or not q or p.val != q.val: 124 | - return False 125 | - return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) 126 | ``` 127 | ##### Time complexity: 128 | O(n) 129 | ##### Space complexity: 130 | O(h) 131 | ##### Notes: 132 | 133 | - Use recursive approach to compare nodes 134 | - Check if values of nodes are equal 135 | - Recursively compare left and right subtrees 136 | 137 | - Use a recursive function to compare nodes 138 | - Handle cases with different tree structures 139 | - Optimize the space complexity if needed 140 | 141 | - Handling cases with different tree structures 142 | 143 | - Modifying the trees 144 | - Using extra space 145 | 146 | ### >> Comparison: 572 Subtree of Another Tree [Easy] *VS* 100 Same Tree [Easy] 147 | > Similarity distance: 0.3645 148 | ##### Similarities 149 | 150 | - Both questions are related to trees and involve comparing two trees. 151 | - Both questions have a binary tree as input. 152 | - Both questions require checking if one tree is a subtree of another tree. 153 | ##### Differences 154 | 155 | - Question 572 requires checking if one tree is a subtree of another tree, while question 100 requires checking if two trees are identical. 156 | - Question 572 allows the subtree to be any part of the larger tree, while question 100 requires the trees to be identical in structure and node values. 157 | - Question 572 has a time complexity of O(m*n), where m and n are the number of nodes in the two trees, while question 100 has a time complexity of O(n), where n is the number of nodes in the tree. 158 | ##### New Insights in 100 Same Tree [Easy] 159 | 160 | - Question 572 can be solved using a recursive approach by checking if the current nodes of the two trees are equal and then recursively checking if the left and right subtrees are equal. 161 | - Question 100 can also be solved using a recursive approach by checking if the current nodes of the two trees are equal and then recursively checking if the left and right subtrees are equal. 162 | - Both questions can be solved using a depth-first search (DFS) approach. 163 | 164 | 165 | --- 166 | # 2. From 100 Same Tree [Easy] to 250 Count Univalue Subtrees [Medium] 167 | > Similarity Distance: 0.3896 168 | 169 | ### >> Reminder: 100 Same Tree [Easy] 170 | Given two binary trees, write a function to check if they are the same or not. 171 | ##### Optimal Python solution: 172 | ```python 173 | 174 | - class Solution: 175 | - def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: 176 | - if not p and not q: 177 | - return True 178 | - if not p or not q or p.val != q.val: 179 | - return False 180 | - return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) 181 | ``` 182 | Check if two binary trees are the same by comparing their nodes recursively. 183 | 184 | ### >> 250 Count Univalue Subtrees [Medium] 185 | Given a binary tree, count the number of uni-value subtrees. A uni-value subtree means all nodes of the subtree have the same value. 186 | ##### Sample input: 187 | 188 | - [5,1,5,5,5,null,5] 189 | ##### Sample output: 190 | 191 | - 4 192 | 193 | ##### Questions to ask to clarify requirements: 194 | 195 | - Can the binary tree be empty? 196 | - Can the binary tree have duplicate values? 197 | - Should the root node be counted as a uni-value subtree? 198 | 199 | ##### Optimal Python solution: 200 | ```python 201 | 202 | - class Solution: 203 | - def countUnivalSubtrees(self, root: TreeNode) -> int: 204 | - self.count = 0 205 | - self.is_unival(root) 206 | - return self.count 207 | - def is_unival(self, node): 208 | - if not node: 209 | - return True 210 | - left_unival = self.is_unival(node.left) 211 | - right_unival = self.is_unival(node.right) 212 | - if (left_unival and right_unival and 213 | - (not node.left or node.left.val == node.val) and 214 | - (not node.right or node.right.val == node.val)): 215 | - self.count += 1 216 | - return True 217 | - return False 218 | ``` 219 | ##### Time complexity: 220 | O(n) 221 | ##### Space complexity: 222 | O(h) 223 | ##### Notes: 224 | 225 | - Count the number of uni-value subtrees 226 | - Recursively check if a subtree is uni-value 227 | - Increment count if a subtree is uni-value 228 | 229 | - Use a helper function to keep track of the count 230 | - Use recursion to traverse the tree 231 | 232 | - Handling the case where the left or right subtree is None 233 | - Incrementing the count only if the current node is a uni-value subtree 234 | 235 | - Using global variables 236 | - Using nested loops 237 | 238 | ### >> Comparison: 100 Same Tree [Easy] *VS* 250 Count Univalue Subtrees [Medium] 239 | > Similarity distance: 0.3896 240 | ##### Similarities 241 | 242 | - Both questions involve traversing a binary tree. 243 | - Both questions require checking the values of nodes in the tree. 244 | ##### Differences 245 | 246 | - Question 100 checks if two trees are structurally identical, while question 250 counts the number of subtrees that have the same value for all nodes. 247 | - Question 100 is classified as an easy problem, while question 250 is classified as a medium problem. 248 | - Question 100 requires comparing two trees, while question 250 requires counting subtrees. 249 | - Question 100 has a time complexity of O(n), while question 250 has a time complexity of O(n^2). 250 | ##### New Insights in 250 Count Univalue Subtrees [Medium] 251 | 252 | - Question 100 can be solved using a recursive approach, where we compare the values of corresponding nodes in the two trees. 253 | - Question 250 can be solved using a recursive approach, where we check if the current subtree is a univalue subtree and recursively check its left and right subtrees. 254 | 255 | 256 | --- 257 | # 3. From 100 Same Tree [Easy] to 98 Validate Binary Search Tree [Medium] 258 | > Similarity Distance: 0.4822 259 | 260 | ### >> Reminder: 100 Same Tree [Easy] 261 | Given two binary trees, write a function to check if they are the same or not. 262 | ##### Optimal Python solution: 263 | ```python 264 | 265 | - class Solution: 266 | - def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: 267 | - if not p and not q: 268 | - return True 269 | - if not p or not q or p.val != q.val: 270 | - return False 271 | - return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) 272 | ``` 273 | Check if two binary trees are the same by comparing their nodes recursively. 274 | 275 | ### >> 98 Validate Binary Search Tree [Medium] 276 | Given the root of a binary tree, determine if it is a valid binary search tree (BST). 277 | ##### Sample input: 278 | [2,1,3] 279 | ##### Sample output: 280 | true 281 | 282 | ##### Questions to ask to clarify requirements: 283 | Can the binary tree have duplicate values? Can we assume the input is a valid binary tree? 284 | 285 | ##### Optimal Python solution: 286 | ```python 287 | class Solution: 288 | def isValidBST(self, root: TreeNode) -> bool: 289 | def helper(node, lower=float('-inf'), upper=float('inf')): 290 | if not node: 291 | return True 292 | val = node.val 293 | if val <= lower or val >= upper: 294 | return False 295 | if not helper(node.right, val, upper): 296 | return False 297 | if not helper(node.left, lower, val): 298 | return False 299 | return True 300 | return helper(root) 301 | ``` 302 | ##### Time complexity: 303 | O(n) 304 | ##### Space complexity: 305 | O(n) 306 | ##### Notes: 307 | 1. Use a helper function to recursively check if each node satisfies the BST property. 308 | 2. Keep track of the lower and upper bounds for each node. 309 | 3. Use the BST property to determine the bounds for the left and right subtrees. 310 | 4. Return True if all nodes satisfy the BST property, otherwise return False. 311 | 1. Use a helper function to recursively check if each node satisfies the BST property. 312 | 2. Keep track of the lower and upper bounds for each node. 313 | 3. Use the BST property to determine the bounds for the left and right subtrees. 314 | 1. Be careful with the lower and upper bounds for each node. 315 | 2. Handle the case when the binary tree has duplicate values. 316 | 1. Avoid using an inorder traversal to check if the tree is a valid BST, as it may require additional space. 317 | 2. Avoid using a brute force approach to check if each node satisfies the BST property. 318 | 319 | ### >> Comparison: 100 Same Tree [Easy] *VS* 98 Validate Binary Search Tree [Medium] 320 | > Similarity distance: 0.4822 321 | ##### Similarities 322 | 323 | - Both questions involve binary trees. 324 | - Both questions require traversing the tree. 325 | - Both questions involve comparing values in the tree nodes. 326 | ##### Differences 327 | 328 | - Question 100 checks if two trees are structurally identical, while question 98 checks if a tree is a valid binary search tree. 329 | - Question 100 requires comparing the values of corresponding nodes in the two trees, while question 98 requires checking the ordering of values in the tree. 330 | - Question 100 has an easy difficulty level, while question 98 has a medium difficulty level. 331 | ##### New Insights in 98 Validate Binary Search Tree [Medium] 332 | 333 | - Question 100 teaches us how to compare the structure of two trees. 334 | - Question 98 teaches us how to validate the ordering of values in a binary search tree. 335 | - Both questions provide practice in tree traversal and comparison techniques. 336 | 337 | 338 | --- 339 | # 4. From 100 Same Tree [Easy] to 101 Symmetric Tree [Easy] 340 | > Similarity Distance: 0.4861 341 | 342 | ### >> Reminder: 100 Same Tree [Easy] 343 | Given two binary trees, write a function to check if they are the same or not. 344 | ##### Optimal Python solution: 345 | ```python 346 | 347 | - class Solution: 348 | - def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: 349 | - if not p and not q: 350 | - return True 351 | - if not p or not q or p.val != q.val: 352 | - return False 353 | - return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) 354 | ``` 355 | Check if two binary trees are the same by comparing their nodes recursively. 356 | 357 | ### >> 101 Symmetric Tree [Easy] 358 | Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). 359 | ##### Sample input: 360 | [1,2,2,3,4,4,3] 361 | ##### Sample output: 362 | true 363 | 364 | ##### Questions to ask to clarify requirements: 365 | Are empty trees considered symmetric? 366 | 367 | ##### Optimal Python solution: 368 | ```python 369 | class Solution: 370 | def isSymmetric(self, root: TreeNode) -> bool: 371 | def isMirror(t1, t2): 372 | if not t1 and not t2: 373 | return True 374 | if not t1 or not t2: 375 | return False 376 | return (t1.val == t2.val) and isMirror(t1.left, t2.right) and isMirror(t1.right, t2.left) 377 | return isMirror(root, root) 378 | ``` 379 | ##### Time complexity: 380 | O(n) 381 | ##### Space complexity: 382 | O(n) 383 | ##### Notes: 384 | 385 | - The tree is symmetric if the left subtree is a mirror reflection of the right subtree. 386 | - Two trees are a mirror reflection of each other if: 1. Their two roots have the same value. 2. The right subtree of each tree is a mirror reflection of the left subtree of the other tree. 387 | Use a helper function to check if two trees are mirror reflections of each other. 388 | The recursive function isMirror takes two trees as arguments and checks if they are mirror reflections of each other. 389 | Avoid using additional data structures. 390 | 391 | ### >> Comparison: 100 Same Tree [Easy] *VS* 101 Symmetric Tree [Easy] 392 | > Similarity distance: 0.4861 393 | ##### Similarities 394 | 395 | - Both questions are related to binary trees. 396 | - Both questions are classified as easy difficulty level. 397 | ##### Differences 398 | 399 | - Question 100 checks if two binary trees are structurally identical, while question 101 checks if a binary tree is symmetric. 400 | - Question 100 compares the entire tree structure, while question 101 compares the left and right subtrees of each node. 401 | - Question 100 requires comparing the values of each node, while question 101 only requires checking the symmetry of the tree. 402 | ##### New Insights in 101 Symmetric Tree [Easy] 403 | 404 | - Question 100 can be solved using recursion by comparing the left and right subtrees of each node. 405 | - Question 101 can be solved using recursion by comparing the left and right subtrees of each node and checking their symmetry. 406 | 407 | 408 | --- 409 | # 5. From 100 Same Tree [Easy] to 545 Boundary of Binary Tree [Medium] 410 | > Similarity Distance: 0.5139 411 | 412 | ### >> Reminder: 100 Same Tree [Easy] 413 | Given two binary trees, write a function to check if they are the same or not. 414 | ##### Optimal Python solution: 415 | ```python 416 | 417 | - class Solution: 418 | - def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: 419 | - if not p and not q: 420 | - return True 421 | - if not p or not q or p.val != q.val: 422 | - return False 423 | - return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) 424 | ``` 425 | Check if two binary trees are the same by comparing their nodes recursively. 426 | 427 | ### >> 545 Boundary of Binary Tree [Medium] 428 | Given a binary tree, return the values of its boundary in anti-clockwise direction starting from root. The boundary includes left boundary, leaves, and right boundary in order without duplicate nodes. 429 | ##### Sample input: 430 | [1,null,2,3,4] 431 | ##### Sample output: 432 | [1,3,4,2] 433 | 434 | ##### Questions to ask to clarify requirements: 435 | What should be the order of the boundary values? What should be included in the boundary? 436 | 437 | ##### Optimal Python solution: 438 | ```python 439 | class Solution: 440 | def boundaryOfBinaryTree(self, root: TreeNode) -> List[int]: 441 | if not root: 442 | return [] 443 | if not root.left and not root.right: 444 | return [root.val] 445 | left_boundary = self.get_left_boundary(root.left) 446 | right_boundary = self.get_right_boundary(root.right) 447 | leaves = self.get_leaves(root) 448 | return [root.val] + left_boundary + leaves + right_boundary 449 | 450 | def get_left_boundary(self, node): 451 | if not node or (not node.left and not node.right): 452 | return [] 453 | left_boundary = [node.val] 454 | if node.left: 455 | left_boundary += self.get_left_boundary(node.left) 456 | else: 457 | left_boundary += self.get_left_boundary(node.right) 458 | return left_boundary 459 | 460 | def get_right_boundary(self, node): 461 | if not node or (not node.left and not node.right): 462 | return [] 463 | right_boundary = [node.val] 464 | if node.right: 465 | right_boundary += self.get_right_boundary(node.right) 466 | else: 467 | right_boundary += self.get_right_boundary(node.left) 468 | return right_boundary 469 | 470 | def get_leaves(self, node): 471 | if not node: 472 | return [] 473 | if not node.left and not node.right: 474 | return [node.val] 475 | return self.get_leaves(node.left) + self.get_leaves(node.right) 476 | ``` 477 | ##### Time complexity: 478 | O(n) 479 | ##### Space complexity: 480 | O(n) 481 | ##### Notes: 482 | 1. The boundary of a binary tree includes the left boundary, leaves, and right boundary. 483 | 2. The left boundary is the path from the root to the leftmost leaf. 484 | 3. The right boundary is the path from the root to the rightmost leaf. 485 | 4. The leaves are the nodes without any children. 486 | 5. The boundary values should be returned in anti-clockwise direction starting from the root. 487 | 6. The boundary values should not contain any duplicate nodes. 488 | 1. Use a recursive approach to traverse the binary tree. 489 | 2. Handle the base cases separately. 490 | 3. Avoid duplicate nodes in the boundary by checking if a node has already been included. 491 | 1. Handling the case when the root has no left or right child. 492 | 2. Handling the case when the left or right boundary is empty. 493 | 3. Avoiding duplicate nodes in the boundary. 494 | 1. Avoid using recursion for each boundary type separately. 495 | 2. Avoid using a separate function for each boundary type. 496 | 497 | ### >> Comparison: 100 Same Tree [Easy] *VS* 545 Boundary of Binary Tree [Medium] 498 | > Similarity distance: 0.5139 499 | ##### Similarities 500 | 501 | - Both questions involve binary trees. 502 | - Both questions require traversing the tree. 503 | - Both questions involve comparing nodes in the tree. 504 | ##### Differences 505 | 506 | - Question 100 is classified as Easy, while question 545 is classified as Medium. 507 | - Question 100 requires checking if two trees are identical, while question 545 requires finding the boundary of a binary tree. 508 | - Question 100 has a time complexity of O(n), while question 545 has a time complexity of O(n^2). 509 | ##### New Insights in 545 Boundary of Binary Tree [Medium] 510 | 511 | - Question 100 can be solved using recursion by comparing the nodes of the two trees. 512 | - Question 545 requires traversing the tree in a specific order to find the boundary nodes. 513 | 514 | 515 | --- 516 | # 6. From 100 Same Tree [Easy] to 226 Invert Binary Tree [Easy] 517 | > Similarity Distance: 0.5204 518 | 519 | ### >> Reminder: 100 Same Tree [Easy] 520 | Given two binary trees, write a function to check if they are the same or not. 521 | ##### Optimal Python solution: 522 | ```python 523 | 524 | - class Solution: 525 | - def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: 526 | - if not p and not q: 527 | - return True 528 | - if not p or not q or p.val != q.val: 529 | - return False 530 | - return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) 531 | ``` 532 | Check if two binary trees are the same by comparing their nodes recursively. 533 | 534 | ### >> 226 Invert Binary Tree [Easy] 535 | Invert a binary tree. 536 | ##### Sample input: 537 | [4,2,7,1,3,6,9] 538 | ##### Sample output: 539 | [4,7,2,9,6,3,1] 540 | 541 | ##### Questions to ask to clarify requirements: 542 | What should the inverted tree look like? 543 | 544 | ##### Optimal Python solution: 545 | ```python 546 | def invertTree(self, root: TreeNode) -> TreeNode: 547 | if root is None: 548 | return None 549 | root.left, root.right = self.invertTree(root.right), self.invertTree(root.left) 550 | return root 551 | ``` 552 | ##### Time complexity: 553 | O(n) 554 | ##### Space complexity: 555 | O(n) 556 | ##### Notes: 557 | 1. Invert a binary tree by swapping the left and right child of each node. 558 | 2. Recursively invert the left and right subtrees. 559 | Use recursion to invert the binary tree. 560 | The inversion can be done recursively by swapping the left and right child of each node. 561 | Inverting the tree by manually rearranging the nodes. 562 | 563 | ### >> Comparison: 100 Same Tree [Easy] *VS* 226 Invert Binary Tree [Easy] 564 | > Similarity distance: 0.5204 565 | ##### Similarities 566 | 567 | - Both questions are related to binary trees. 568 | - Both questions have a recursive solution. 569 | - Both questions have a time complexity of O(n). 570 | ##### Differences 571 | 572 | - Question 100 checks if two binary trees are structurally identical, while question 226 inverts a binary tree. 573 | - Question 100 compares the values of corresponding nodes, while question 226 swaps the left and right child of each node. 574 | - Question 100 returns true if the trees are the same, while question 226 modifies the original tree and returns the inverted tree. 575 | ##### New Insights in 226 Invert Binary Tree [Easy] 576 | 577 | - Question 100 can be solved by comparing the values of corresponding nodes and recursively checking the left and right subtrees. 578 | - Question 226 can be solved by swapping the left and right child of each node and recursively inverting the left and right subtrees. 579 | 580 | -------------------------------------------------------------------------------- /intensive_study_guides/20231226_040350/leetcode_intensive_day_000004.md: -------------------------------------------------------------------------------- 1 | 2 | # Leetcode Intensive Tutorial Day 4 3 | > [Difficulty Score: 12] 4 | 5 | > [Version: 20231226_040350] 6 | 7 | > [Including this day, you had studied : 28 leetcode problems] 8 | 9 | 10 | ## Courses overview of the day 11 | 12 | - 521 Longest Uncommon Subsequence I [Easy] 13 | - 58 Length of Last Word [Easy] 14 | - 557 Reverse Words in a String III [Easy] 15 | - 151 Reverse Words in a String [Medium] 16 | - 418 Sentence Screen Fitting [Medium] 17 | - 68 Text Justification [Hard] 18 | - 434 Number of Segments in a String [Easy] 19 | 20 | #### Step by step 21 | 22 | - [1. From 521 Longest Uncommon Subsequence I [Easy] to 58 Length of Last Word [Easy]](#1-from-521-longest-uncommon-subsequence-i-easy-to-58-length-of-last-word-easy)) 23 | 24 | - [2. From 58 Length of Last Word [Easy] to 557 Reverse Words in a String III [Easy]](#2-from-58-length-of-last-word-easy-to-557-reverse-words-in-a-string-iii-easy)) 25 | 26 | - [3. From 557 Reverse Words in a String III [Easy] to 151 Reverse Words in a String [Medium]](#3-from-557-reverse-words-in-a-string-iii-easy-to-151-reverse-words-in-a-string-medium)) 27 | 28 | - [4. From 557 Reverse Words in a String III [Easy] to 418 Sentence Screen Fitting [Medium]](#4-from-557-reverse-words-in-a-string-iii-easy-to-418-sentence-screen-fitting-medium)) 29 | 30 | - [5. From 418 Sentence Screen Fitting [Medium] to 68 Text Justification [Hard]](#5-from-418-sentence-screen-fitting-medium-to-68-text-justification-hard)) 31 | 32 | - [6. From 557 Reverse Words in a String III [Easy] to 434 Number of Segments in a String [Easy]](#6-from-557-reverse-words-in-a-string-iii-easy-to-434-number-of-segments-in-a-string-easy)) 33 | 34 | 35 | 36 | #### Summary 37 | 38 | 39 | - 521 Longest Uncommon Subsequence I : The essence of this question is to find the longest uncommon subsequence of two strings. 40 | - 58 Length of Last Word : Given a string s consists of some words separated by spaces, return the length of the last word in the string. 41 | - 418 Sentence Screen Fitting : Given a screen and a sentence, find the number of times the sentence can be fitted on the screen. 42 | - 557 Reverse Words in a String III : Reverse the order of characters in each word within a sentence while preserving whitespace and initial word order. 43 | - 434 Number of Segments in a String : Count the number of segments in a string, where a segment is defined to be a contiguous sequence of non-space characters. 44 | - 151 Reverse Words in a String : The essence of this problem is to reverse the words in a string. 45 | - 68 Text Justification : Formatting text by adding words to lines and justifying the lines. 46 | > Similarity Diameter of these problems: 0.5766 47 | 48 | 49 | --- 50 | # 1. From 521 Longest Uncommon Subsequence I [Easy] to 58 Length of Last Word [Easy] 51 | > Similarity Distance: 0.4655 52 | 53 | ### >> 521 Longest Uncommon Subsequence I [Easy] 54 | Given two strings, you need to find the longest uncommon subsequence of this two strings. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other string. 55 | ##### Sample input: 56 | "aba" 57 | "cdc" 58 | ##### Sample output: 59 | 3 60 | 61 | ##### Questions to ask to clarify requirements: 62 | What is a subsequence of a string? 63 | 64 | ##### Optimal Python solution: 65 | ```python 66 | def findLUSlength(a: str, b: str) -> int: 67 | if a == b: 68 | return -1 69 | else: 70 | return max(len(a), len(b)) 71 | ``` 72 | ##### Time complexity: 73 | O(1) 74 | ##### Space complexity: 75 | O(1) 76 | ##### Notes: 77 | 1. The longest uncommon subsequence is the longer string if the two strings are different. 78 | 2. If the two strings are the same, there is no uncommon subsequence. 79 | 3. The longest uncommon subsequence cannot be a subsequence of the other string. 80 | There is no specific programming tip for this question. 81 | There is no tricky part in this question. 82 | There is no specific thing to avoid in this question. 83 | 84 | ### >> 58 Length of Last Word [Easy] 85 | Given a string s consists of some words separated by spaces, return the length of the last word in the string. If the last word does not exist, return 0. 86 | ##### Sample input: 87 | "Hello World" 88 | ##### Sample output: 89 | 5 90 | 91 | ##### Questions to ask to clarify requirements: 92 | 93 | - Can the string be empty? 94 | - Can the string contain leading or trailing spaces? 95 | 96 | ##### Optimal Python solution: 97 | ```python 98 | def lengthOfLastWord(s): 99 | words = s.split() 100 | if len(words) == 0: 101 | return 0 102 | return len(words[-1]) 103 | ``` 104 | ##### Time complexity: 105 | O(n) 106 | ##### Space complexity: 107 | O(n) 108 | ##### Notes: 109 | 110 | - Split the string into words using spaces as separators. 111 | - Return the length of the last word in the list of words. 112 | - Handle the cases where the string is empty or contains only spaces. 113 | 114 | - Use the split() method to split the string into words using spaces as separators. 115 | - Handle the cases where the string is empty or contains only spaces by checking the length of the resulting list of words. 116 | 117 | - Handling the cases where the string is empty or contains only spaces. 118 | 119 | - Using regular expressions to split the string. 120 | 121 | ### >> Comparison: 521 Longest Uncommon Subsequence I [Easy] *VS* 58 Length of Last Word [Easy] 122 | > Similarity distance: 0.4655 123 | ##### Similarities 124 | 125 | - Both questions are classified as 'Easy' level. 126 | - Both questions involve string manipulation. 127 | - Both questions require finding the length of a subsequence or word. 128 | ##### Differences 129 | 130 | - Question 521: Longest Uncommon Subsequence I involves finding the length of the longest uncommon subsequence between two strings. 131 | - Question 58: Length of Last Word involves finding the length of the last word in a given string. 132 | ##### New Insights in 58 Length of Last Word [Easy] 133 | 134 | - Question 521: Longest Uncommon Subsequence I introduces the concept of uncommon subsequences, which are subsequences that do not appear in both strings. 135 | - Question 58: Length of Last Word introduces the concept of finding the length of the last word in a string, which requires handling whitespace and edge cases. 136 | 137 | 138 | --- 139 | # 2. From 58 Length of Last Word [Easy] to 557 Reverse Words in a String III [Easy] 140 | > Similarity Distance: 0.4289 141 | 142 | ### >> Reminder: 58 Length of Last Word [Easy] 143 | Given a string s consists of some words separated by spaces, return the length of the last word in the string. If the last word does not exist, return 0. 144 | ##### Optimal Python solution: 145 | ```python 146 | def lengthOfLastWord(s): 147 | words = s.split() 148 | if len(words) == 0: 149 | return 0 150 | return len(words[-1]) 151 | ``` 152 | Given a string s consists of some words separated by spaces, return the length of the last word in the string. 153 | 154 | ### >> 557 Reverse Words in a String III [Easy] 155 | Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. 156 | ##### Sample input: 157 | "Let's take LeetCode contest" 158 | ##### Sample output: 159 | "s'teL ekat edoCteeL tsetnoc" 160 | 161 | ##### Questions to ask to clarify requirements: 162 | Are the words separated by a single space? Can the input string be empty? 163 | 164 | ##### Optimal Python solution: 165 | ```python 166 | def reverseWords(s): 167 | return ' '.join(word[::-1] for word in s.split()) 168 | ``` 169 | ##### Time complexity: 170 | O(n) 171 | ##### Space complexity: 172 | O(n) 173 | ##### Notes: 174 | 1. Split the string into words 175 | 2. Reverse each word 176 | 3. Join the reversed words with a space 177 | No specific tips 178 | No tricky parts 179 | No specific pitfalls 180 | 181 | ### >> Comparison: 58 Length of Last Word [Easy] *VS* 557 Reverse Words in a String III [Easy] 182 | > Similarity distance: 0.4289 183 | ##### Similarities 184 | 185 | - Both questions are classified as 'Easy' level. 186 | - Both questions involve manipulating strings. 187 | - Both questions require reversing or extracting words from a string. 188 | ##### Differences 189 | 190 | - Question 58 focuses on finding the length of the last word in a string. 191 | - Question 557 focuses on reversing the order of words in a string. 192 | ##### New Insights in 557 Reverse Words in a String III [Easy] 193 | 194 | - Question 58 teaches us how to find the length of the last word in a string by utilizing string manipulation techniques. 195 | - Question 557 teaches us how to reverse the order of words in a string by utilizing string manipulation techniques. 196 | 197 | 198 | --- 199 | # 3. From 557 Reverse Words in a String III [Easy] to 151 Reverse Words in a String [Medium] 200 | > Similarity Distance: 0.2405 201 | 202 | ### >> Reminder: 557 Reverse Words in a String III [Easy] 203 | Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. 204 | ##### Optimal Python solution: 205 | ```python 206 | def reverseWords(s): 207 | return ' '.join(word[::-1] for word in s.split()) 208 | ``` 209 | Reverse the order of characters in each word within a sentence while preserving whitespace and initial word order. 210 | 211 | ### >> 151 Reverse Words in a String [Medium] 212 | Given an input string, reverse the string word by word. 213 | ##### Sample input: 214 | s = "the sky is blue" 215 | Output: "blue is sky the" 216 | ##### Sample output: 217 | "blue is sky the" 218 | 219 | ##### Questions to ask to clarify requirements: 220 | What should be the output if the input string is empty? Can the input string contain leading or trailing spaces? 221 | 222 | ##### Optimal Python solution: 223 | ```python 224 | def reverseWords(s): 225 | return ' '.join(s.split()[::-1]) 226 | ``` 227 | ##### Time complexity: 228 | O(n) 229 | ##### Space complexity: 230 | O(n) 231 | ##### Notes: 232 | 1. Split the input string into a list of words. 233 | 2. Reverse the list of words. 234 | 3. Join the reversed list of words with spaces. 235 | 1. Use built-in functions like split(), reverse(), and join() for string manipulation. 236 | 2. Handle edge cases like empty string and leading/trailing spaces. 237 | 3. Consider using two pointers to reverse a list in-place. 238 | 1. Handling leading and trailing spaces. 239 | 2. Handling multiple spaces between words. 240 | 1. Using built-in functions like split() and join(). 241 | 2. Using extra space. 242 | 243 | ### >> Comparison: 557 Reverse Words in a String III [Easy] *VS* 151 Reverse Words in a String [Medium] 244 | > Similarity distance: 0.2405 245 | ##### Similarities 246 | 247 | - Both questions involve reversing the order of words in a string. 248 | ##### Differences 249 | 250 | - Question 557 is classified as Easy, while question 151 is classified as Medium. 251 | - Question 557 requires reversing the order of characters within each word, while question 151 does not. 252 | - Question 557 allows leading and trailing spaces, while question 151 does not. 253 | - Question 557 has a constraint on the length of the input string, while question 151 does not. 254 | ##### New Insights in 151 Reverse Words in a String [Medium] 255 | 256 | - Question 557 requires a two-pointer approach to reverse the order of characters within each word. 257 | - Question 151 can be solved using a three-step approach: reverse the entire string, reverse each word, and remove extra spaces. 258 | 259 | 260 | --- 261 | # 4. From 557 Reverse Words in a String III [Easy] to 418 Sentence Screen Fitting [Medium] 262 | > Similarity Distance: 0.3969 263 | 264 | ### >> Reminder: 557 Reverse Words in a String III [Easy] 265 | Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. 266 | ##### Optimal Python solution: 267 | ```python 268 | def reverseWords(s): 269 | return ' '.join(word[::-1] for word in s.split()) 270 | ``` 271 | Reverse the order of characters in each word within a sentence while preserving whitespace and initial word order. 272 | 273 | ### >> 418 Sentence Screen Fitting [Medium] 274 | Given a rows x cols screen and a sentence represented as a list of strings, return the number of times the given sentence can be fitted on the screen. 275 | ##### Sample input: 276 | 277 | - rows = 3, cols = 6, sentence = ["a", "bcd", "e"] 278 | ##### Sample output: 279 | 280 | - 2 281 | 282 | ##### Questions to ask to clarify requirements: 283 | 284 | - Can the screen have empty rows? 285 | - Can the screen have empty columns? 286 | - Can the sentence be empty? 287 | - Can the sentence contain empty strings? 288 | - Can the sentence contain strings longer than the screen width? 289 | 290 | ##### Optimal Python solution: 291 | ```python 292 | 293 | - from typing import List 294 | - 295 | - class Solution: 296 | - def wordsTyping(self, sentence: List[str], rows: int, cols: int) -> int: 297 | - s = ' '.join(sentence) + ' ' 298 | - start = 0 299 | - n = len(s) 300 | - for i in range(rows): 301 | - start += cols 302 | - if s[start % n] == ' ': 303 | - start += 1 304 | - else: 305 | - while start > 0 and s[(start - 1) % n] != ' ': 306 | - start -= 1 307 | - return start // n 308 | - 309 | - solution = Solution() 310 | - result = solution.wordsTyping(["a", "bcd", "e"], 3, 6) 311 | - print(result) 312 | ``` 313 | ##### Time complexity: 314 | O(rows + n) 315 | ##### Space complexity: 316 | O(n) 317 | ##### Notes: 318 | 319 | - Join the sentence into a single string with spaces 320 | - Iterate over the rows and count the number of times the sentence can be fitted 321 | 322 | - Use the modulo operator to handle wrapping around the string 323 | - Optimize the solution by avoiding unnecessary iterations 324 | 325 | - Using modulo operator to handle wrapping around the string 326 | 327 | - Using a nested loop to iterate over the screen 328 | 329 | ### >> Comparison: 557 Reverse Words in a String III [Easy] *VS* 418 Sentence Screen Fitting [Medium] 330 | > Similarity distance: 0.3969 331 | ##### Similarities 332 | 333 | - Both questions involve manipulating strings. 334 | - Both questions require iterating through the input string. 335 | - Both questions involve reversing parts of the string. 336 | ##### Differences 337 | 338 | - Question 557 reverses each word in the string, while question 418 fits sentences on a screen. 339 | - Question 557 operates on individual words, while question 418 operates on complete sentences. 340 | - Question 557 requires reversing the order of characters within each word, while question 418 requires fitting sentences on multiple lines. 341 | - Question 557 has an easy difficulty level, while question 418 has a medium difficulty level. 342 | ##### New Insights in 418 Sentence Screen Fitting [Medium] 343 | 344 | - Question 557 teaches us how to reverse the order of characters within a word. 345 | - Question 418 teaches us how to fit sentences on multiple lines based on screen width. 346 | 347 | 348 | --- 349 | # 5. From 418 Sentence Screen Fitting [Medium] to 68 Text Justification [Hard] 350 | > Similarity Distance: 0.5103 351 | 352 | ### >> Reminder: 418 Sentence Screen Fitting [Medium] 353 | Given a rows x cols screen and a sentence represented as a list of strings, return the number of times the given sentence can be fitted on the screen. 354 | ##### Optimal Python solution: 355 | ```python 356 | 357 | - from typing import List 358 | - 359 | - class Solution: 360 | - def wordsTyping(self, sentence: List[str], rows: int, cols: int) -> int: 361 | - s = ' '.join(sentence) + ' ' 362 | - start = 0 363 | - n = len(s) 364 | - for i in range(rows): 365 | - start += cols 366 | - if s[start % n] == ' ': 367 | - start += 1 368 | - else: 369 | - while start > 0 and s[(start - 1) % n] != ' ': 370 | - start -= 1 371 | - return start // n 372 | - 373 | - solution = Solution() 374 | - result = solution.wordsTyping(["a", "bcd", "e"], 3, 6) 375 | - print(result) 376 | ``` 377 | Given a screen and a sentence, find the number of times the sentence can be fitted on the screen. 378 | 379 | ### >> 68 Text Justification [Hard] 380 | Given an array of words and a width maxWidth, format the text such that each line has exactly maxWidth characters and is fully (left and right) justified. 381 | ##### Sample input: 382 | ["This", "is", "an", "example", "of", "text", "justification."], 16 383 | ##### Sample output: 384 | ["This is an", "example of text", "justification. "] 385 | 386 | ##### Questions to ask to clarify requirements: 387 | What should be done if a word cannot fit in a line with maxWidth characters? 388 | 389 | ##### Optimal Python solution: 390 | ```python 391 | def fullJustify(words: List[str], maxWidth: int) -> List[str]: 392 | result = [] 393 | line = [] 394 | line_length = 0 395 | for word in words: 396 | if line_length + len(line) + len(word) <= maxWidth: 397 | line.append(word) 398 | line_length += len(word) 399 | else: 400 | num_spaces = maxWidth - line_length 401 | if len(line) == 1: 402 | result.append(line[0] + ' ' * num_spaces) 403 | else: 404 | num_gaps = len(line) - 1 405 | spaces_per_gap = num_spaces // num_gaps 406 | extra_spaces = num_spaces % num_gaps 407 | justified_line = '' 408 | for i in range(len(line) - 1): 409 | justified_line += line[i] + ' ' * spaces_per_gap 410 | if i < extra_spaces: 411 | justified_line += ' ' 412 | justified_line += line[-1] 413 | result.append(justified_line) 414 | line = [word] 415 | line_length = len(word) 416 | result.append(' '.join(line).ljust(maxWidth)) 417 | return result 418 | ``` 419 | ##### Time complexity: 420 | O(n) 421 | ##### Space complexity: 422 | O(n) 423 | ##### Notes: 424 | 1. Iterate through the words and add them to a line until the line length exceeds maxWidth. 425 | 2. Justify the line by evenly distributing the extra spaces between the words. 426 | 3. Add the justified line to the result. 427 | 4. Repeat until all words have been processed. 428 | Use the built-in functions len() and ljust() to calculate the length of a line and add spaces to the right side of a line. 429 | Handling the last line and the case when a word cannot fit in a line with maxWidth characters. 430 | Creating a new string for each line. 431 | 432 | ### >> Comparison: 418 Sentence Screen Fitting [Medium] *VS* 68 Text Justification [Hard] 433 | > Similarity distance: 0.5103 434 | ##### Similarities 435 | 436 | - Both questions involve manipulating strings and solving text formatting problems. 437 | - Both questions require careful consideration of word boundaries and line breaks. 438 | - Both questions involve optimizing the placement of words within a given space. 439 | ##### Differences 440 | 441 | - 418 Sentence Screen Fitting focuses on fitting sentences into a screen with a fixed width and height. 442 | - 68 Text Justification focuses on justifying text by adding spaces between words to achieve a balanced appearance. 443 | - 418 Sentence Screen Fitting has a linear time complexity solution, while 68 Text Justification has a more complex solution with a time complexity of O(n^2). 444 | ##### New Insights in 68 Text Justification [Hard] 445 | 446 | - From 418 Sentence Screen Fitting, we can learn how to efficiently fit sentences into a screen by considering word boundaries and line breaks. 447 | - From 68 Text Justification, we can learn how to justify text by adding spaces between words to achieve a balanced appearance. 448 | 449 | 450 | --- 451 | # 6. From 557 Reverse Words in a String III [Easy] to 434 Number of Segments in a String [Easy] 452 | > Similarity Distance: 0.4248 453 | 454 | ### >> Reminder: 557 Reverse Words in a String III [Easy] 455 | Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. 456 | ##### Optimal Python solution: 457 | ```python 458 | def reverseWords(s): 459 | return ' '.join(word[::-1] for word in s.split()) 460 | ``` 461 | Reverse the order of characters in each word within a sentence while preserving whitespace and initial word order. 462 | 463 | ### >> 434 Number of Segments in a String [Easy] 464 | Count the number of segments in a string, where a segment is defined to be a contiguous sequence of non-space characters. 465 | ##### Sample input: 466 | "Hello, my name is John" 467 | ##### Sample output: 468 | 5 469 | 470 | ##### Questions to ask to clarify requirements: 471 | 472 | - Can there be multiple spaces between words? 473 | - Should we count empty segments? 474 | 475 | ##### Optimal Python solution: 476 | ```python 477 | 478 | - def countSegments(s: str) -> int: 479 | - return len(s.split()) 480 | ``` 481 | ##### Time complexity: 482 | O(N) 483 | ##### Space complexity: 484 | O(N) 485 | ##### Notes: 486 | 487 | - Split the string by spaces 488 | - Count the number of non-empty segments 489 | 490 | - Use the split function to split the string by spaces. 491 | - Use the len function to get the count of segments. 492 | 493 | - Handling multiple spaces between words 494 | 495 | - Using regular expressions 496 | 497 | ### >> Comparison: 557 Reverse Words in a String III [Easy] *VS* 434 Number of Segments in a String [Easy] 498 | > Similarity distance: 0.4248 499 | ##### Similarities 500 | 501 | - Both questions are classified as 'Easy' level. 502 | - Both questions involve manipulating strings. 503 | - Both questions require reversing or counting segments in a string. 504 | ##### Differences 505 | 506 | - 557 Reverse Words in a String III focuses on reversing individual words in a string, while 434 Number of Segments in a String focuses on counting the number of segments in a string. 507 | - 557 Reverse Words in a String III reverses the order of characters within each word, while 434 Number of Segments in a String counts the number of segments separated by spaces. 508 | - 557 Reverse Words in a String III requires reversing the entire string, while 434 Number of Segments in a String does not require any string reversal. 509 | ##### New Insights in 434 Number of Segments in a String [Easy] 510 | 511 | - From 557 Reverse Words in a String III, we can learn how to reverse the order of characters within each word in a string. 512 | - From 434 Number of Segments in a String, we can learn how to count the number of segments in a string by identifying the spaces between segments. 513 | 514 | -------------------------------------------------------------------------------- /intensive_study_guides/20231226_040350/leetcode_intensive_day_000005.md: -------------------------------------------------------------------------------- 1 | 2 | # Leetcode Intensive Tutorial Day 5 3 | > [Difficulty Score: 12] 4 | 5 | > [Version: 20231226_040350] 6 | 7 | > [Including this day, you had studied : 35 leetcode problems] 8 | 9 | 10 | ## Courses overview of the day 11 | 12 | - 414 Third Maximum Number [Easy] 13 | - 217 Contains Duplicate [Easy] 14 | - 384 Shuffle an Array [Medium] 15 | - 82 Remove Duplicates from Sorted List II [Medium] 16 | - 83 Remove Duplicates from Sorted List [Easy] 17 | - 26 Remove Duplicates from Sorted Array [Easy] 18 | - 316 Remove Duplicate Letters [Hard] 19 | 20 | #### Step by step 21 | 22 | - [1. From 414 Third Maximum Number [Easy] to 217 Contains Duplicate [Easy]](#1-from-414-third-maximum-number-easy-to-217-contains-duplicate-easy)) 23 | 24 | - [2. From 217 Contains Duplicate [Easy] to 384 Shuffle an Array [Medium]](#2-from-217-contains-duplicate-easy-to-384-shuffle-an-array-medium)) 25 | 26 | - [3. From 414 Third Maximum Number [Easy] to 82 Remove Duplicates from Sorted List II [Medium]](#3-from-414-third-maximum-number-easy-to-82-remove-duplicates-from-sorted-list-ii-medium)) 27 | 28 | - [4. From 82 Remove Duplicates from Sorted List II [Medium] to 83 Remove Duplicates from Sorted List [Easy]](#4-from-82-remove-duplicates-from-sorted-list-ii-medium-to-83-remove-duplicates-from-sorted-list-easy)) 29 | 30 | - [5. From 82 Remove Duplicates from Sorted List II [Medium] to 26 Remove Duplicates from Sorted Array [Easy]](#5-from-82-remove-duplicates-from-sorted-list-ii-medium-to-26-remove-duplicates-from-sorted-array-easy)) 31 | 32 | - [6. From 82 Remove Duplicates from Sorted List II [Medium] to 316 Remove Duplicate Letters [Hard]](#6-from-82-remove-duplicates-from-sorted-list-ii-medium-to-316-remove-duplicate-letters-hard)) 33 | 34 | 35 | 36 | #### Summary 37 | 38 | 39 | - 384 Shuffle an Array : Store the original array and a shuffled copy. Use the random.shuffle() function to shuffle the copy when needed. 40 | - 316 Remove Duplicate Letters : Remove duplicate letters from a string and keep the result in lexicographical order. 41 | - 82 Remove Duplicates from Sorted List II : Remove duplicates from sorted linked list. 42 | - 414 Third Maximum Number : Return the third maximum number in an array, or the maximum number if it does not exist. 43 | - 217 Contains Duplicate : Check for duplicate elements in an array using a set. 44 | - 26 Remove Duplicates from Sorted Array : Removing duplicates from a sorted array in-place. 45 | - 83 Remove Duplicates from Sorted List : The essence of this problem is to remove duplicates from a sorted linked list. 46 | > Similarity Diameter of these problems: 0.5712 47 | 48 | 49 | --- 50 | # 1. From 414 Third Maximum Number [Easy] to 217 Contains Duplicate [Easy] 51 | > Similarity Distance: 0.4657 52 | 53 | ### >> 414 Third Maximum Number [Easy] 54 | Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. 55 | ##### Sample input: 56 | [3, 2, 1] 57 | ##### Sample output: 58 | 1 59 | 60 | ##### Questions to ask to clarify requirements: 61 | 62 | - What should be returned if the array contains less than three distinct numbers? 63 | - Can the array contain negative numbers? 64 | - Can the array be empty? 65 | 66 | ##### Optimal Python solution: 67 | ```python 68 | def thirdMax(nums): 69 | nums = list(set(nums)) 70 | if len(nums) < 3: 71 | return max(nums) 72 | else: 73 | nums.remove(max(nums)) 74 | nums.remove(max(nums)) 75 | return max(nums) 76 | ``` 77 | ##### Time complexity: 78 | O(n) 79 | ##### Space complexity: 80 | O(n) 81 | ##### Notes: 82 | 83 | - Remove duplicates from the array using a set. 84 | - If the length of the array is less than 3, return the maximum number. 85 | - Otherwise, remove the first and second maximum numbers and return the maximum number. 86 | 87 | - Understand the definition of distinct numbers. 88 | - Use a set to remove duplicates from the array. 89 | - Handle edge cases such as arrays with less than three distinct numbers. 90 | 91 | - Handling edge cases such as arrays with less than three distinct numbers. 92 | - Removing the first and second maximum numbers from the array. 93 | 94 | - Sorting the array and returning the third maximum number. 95 | - Using extra space to store intermediate results. 96 | 97 | ### >> 217 Contains Duplicate [Easy] 98 | Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct. 99 | ##### Sample input: 100 | [1,2,3,1] 101 | ##### Sample output: 102 | true 103 | 104 | ##### Questions to ask to clarify requirements: 105 | Are negative numbers allowed in the array? 106 | 107 | ##### Optimal Python solution: 108 | ```python 109 | def containsDuplicate(nums): 110 | return len(nums) != len(set(nums)) 111 | ``` 112 | ##### Time complexity: 113 | O(n) 114 | ##### Space complexity: 115 | O(n) 116 | ##### Notes: 117 | Use a set to check for duplicate elements. 118 | Use the set data structure to efficiently check for duplicate elements. 119 | None 120 | None 121 | 122 | ### >> Comparison: 414 Third Maximum Number [Easy] *VS* 217 Contains Duplicate [Easy] 123 | > Similarity distance: 0.4657 124 | ##### Similarities 125 | 126 | - Both questions are classified as 'Easy' level. 127 | - Both questions involve manipulating arrays. 128 | - Both questions require finding a specific value in an array. 129 | ##### Differences 130 | 131 | - Question 414 involves finding the third maximum number in an array, while question 217 involves finding duplicate elements in an array. 132 | - Question 414 requires returning the third maximum number, while question 217 requires returning whether there are any duplicate elements. 133 | - Question 414 has a time complexity requirement of O(n), while question 217 does not have a specific time complexity requirement. 134 | ##### New Insights in 217 Contains Duplicate [Easy] 135 | 136 | - Question 414: To find the third maximum number, we can use a set to keep track of the three maximum numbers encountered so far. 137 | - Question 217: To check for duplicate elements, we can use a set to keep track of the unique elements encountered so far. 138 | 139 | 140 | --- 141 | # 2. From 217 Contains Duplicate [Easy] to 384 Shuffle an Array [Medium] 142 | > Similarity Distance: 0.5267 143 | 144 | ### >> Reminder: 217 Contains Duplicate [Easy] 145 | Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct. 146 | ##### Optimal Python solution: 147 | ```python 148 | def containsDuplicate(nums): 149 | return len(nums) != len(set(nums)) 150 | ``` 151 | Check for duplicate elements in an array using a set. 152 | 153 | ### >> 384 Shuffle an Array [Medium] 154 | Design an algorithm to randomly shuffle an array of distinct numbers without using the Fisher-Yates shuffle algorithm. 155 | ##### Sample input: 156 | [1, 2, 3] 157 | [1, 2, 3, 4, 5, 6, 7, 8, 9] 158 | ##### Sample output: 159 | Random output 160 | Random output 161 | 162 | ##### Questions to ask to clarify requirements: 163 | Can we assume the input array always contains distinct numbers? Can we use the random.shuffle() function? 164 | 165 | ##### Optimal Python solution: 166 | ```python 167 | import random 168 | 169 | class Solution: 170 | 171 | def __init__(self, nums: List[int]): 172 | self.original = nums 173 | self.shuffled = nums.copy() 174 | 175 | def reset(self) -> List[int]: 176 | return self.original 177 | 178 | def shuffle(self) -> List[int]: 179 | random.shuffle(self.shuffled) 180 | return self.shuffled 181 | ``` 182 | ##### Time complexity: 183 | O(n) 184 | ##### Space complexity: 185 | O(n) 186 | ##### Notes: 187 | Store the original array and a shuffled copy. Use the random.shuffle() function to shuffle the copy when needed. 188 | Use the copy() method to create a copy of the array. 189 | None 190 | None 191 | 192 | ### >> Comparison: 217 Contains Duplicate [Easy] *VS* 384 Shuffle an Array [Medium] 193 | > Similarity distance: 0.5267 194 | ##### Similarities 195 | 196 | - Both questions involve manipulating an array. 197 | - Both questions require checking for duplicates in the array. 198 | ##### Differences 199 | 200 | - Question 217 is classified as Easy, while question 384 is classified as Medium. 201 | - Question 217 asks to determine if the array contains any duplicates, while question 384 asks to shuffle the array randomly. 202 | - Question 217 can be solved using a hash set to check for duplicates, while question 384 requires implementing the Fisher-Yates shuffle algorithm. 203 | ##### New Insights in 384 Shuffle an Array [Medium] 204 | 205 | - Question 217 teaches us how to efficiently check for duplicates in an array using a hash set. 206 | - Question 384 introduces us to the Fisher-Yates shuffle algorithm, which is used to randomly shuffle an array. 207 | 208 | 209 | --- 210 | # 3. From 414 Third Maximum Number [Easy] to 82 Remove Duplicates from Sorted List II [Medium] 211 | > Similarity Distance: 0.4678 212 | 213 | ### >> Reminder: 414 Third Maximum Number [Easy] 214 | Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. 215 | ##### Optimal Python solution: 216 | ```python 217 | def thirdMax(nums): 218 | nums = list(set(nums)) 219 | if len(nums) < 3: 220 | return max(nums) 221 | else: 222 | nums.remove(max(nums)) 223 | nums.remove(max(nums)) 224 | return max(nums) 225 | ``` 226 | Return the third maximum number in an array, or the maximum number if it does not exist. 227 | 228 | ### >> 82 Remove Duplicates from Sorted List II [Medium] 229 | Given the head of a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Return the linked list sorted as well. 230 | ##### Sample input: 231 | [1,2,3,3,4,4,5] 232 | ##### Sample output: 233 | [1,2,5] 234 | 235 | ##### Questions to ask to clarify requirements: 236 | 237 | - Can the linked list be empty? 238 | - Can the linked list contain negative numbers? 239 | - Can the linked list contain cycles? 240 | 241 | ##### Optimal Python solution: 242 | ```python 243 | def deleteDuplicates(head): 244 | dummy = ListNode(0) 245 | dummy.next = head 246 | prev = dummy 247 | curr = head 248 | while curr: 249 | while curr.next and curr.val == curr.next.val: 250 | curr = curr.next 251 | if prev.next == curr: 252 | prev = prev.next 253 | else: 254 | prev.next = curr.next 255 | curr = curr.next 256 | return dummy.next 257 | ``` 258 | ##### Time complexity: 259 | O(n) 260 | ##### Space complexity: 261 | O(1) 262 | ##### Notes: 263 | 264 | - Use a dummy node to handle the case where the head of the linked list is a duplicate. 265 | - Iterate through the linked list and skip duplicate nodes. 266 | - Update the previous node's next pointer to skip duplicate nodes. 267 | 268 | - Use a dummy node to handle the case where the head of the linked list is a duplicate. 269 | - Iterate through the linked list and skip duplicate nodes. 270 | - Update the previous node's next pointer to skip duplicate nodes. 271 | 272 | - Handling the case where the head of the linked list is a duplicate. 273 | - Updating the previous node's next pointer to skip duplicate nodes. 274 | 275 | - Using extra space. 276 | - Using recursion. 277 | 278 | ### >> Comparison: 414 Third Maximum Number [Easy] *VS* 82 Remove Duplicates from Sorted List II [Medium] 279 | > Similarity distance: 0.4678 280 | ##### Similarities 281 | 282 | - Both questions involve manipulating arrays or linked lists. 283 | - Both questions require finding and removing duplicates. 284 | - Both questions have a specific condition to determine the maximum or minimum value. 285 | ##### Differences 286 | 287 | - 414 Third Maximum Number: Involves finding the third maximum number in an array. 288 | - 82 Remove Duplicates from Sorted List II: Involves removing duplicates from a sorted linked list and keeping only distinct elements. 289 | ##### New Insights in 82 Remove Duplicates from Sorted List II [Medium] 290 | 291 | - 414 Third Maximum Number: The solution requires keeping track of the three maximum numbers using three variables. 292 | - 82 Remove Duplicates from Sorted List II: The solution requires using a dummy node and two pointers to remove duplicates. 293 | 294 | 295 | --- 296 | # 4. From 82 Remove Duplicates from Sorted List II [Medium] to 83 Remove Duplicates from Sorted List [Easy] 297 | > Similarity Distance: 0.3366 298 | 299 | ### >> Reminder: 82 Remove Duplicates from Sorted List II [Medium] 300 | Given the head of a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Return the linked list sorted as well. 301 | ##### Optimal Python solution: 302 | ```python 303 | def deleteDuplicates(head): 304 | dummy = ListNode(0) 305 | dummy.next = head 306 | prev = dummy 307 | curr = head 308 | while curr: 309 | while curr.next and curr.val == curr.next.val: 310 | curr = curr.next 311 | if prev.next == curr: 312 | prev = prev.next 313 | else: 314 | prev.next = curr.next 315 | curr = curr.next 316 | return dummy.next 317 | ``` 318 | Remove duplicates from sorted linked list. 319 | 320 | ### >> 83 Remove Duplicates from Sorted List [Easy] 321 | Given a sorted linked list, delete all duplicates such that each element appears only once. 322 | ##### Sample input: 323 | 1->1->2 324 | 1->1->2->3->3 325 | ##### Sample output: 326 | 1->2 327 | 1->2->3 328 | 329 | ##### Questions to ask to clarify requirements: 330 | What is the format of the linked list? Can the input list be empty? 331 | 332 | ##### Optimal Python solution: 333 | ```python 334 | class Solution: 335 | def deleteDuplicates(self, head: ListNode) -> ListNode: 336 | if not head: 337 | return head 338 | curr = head 339 | while curr.next: 340 | if curr.val == curr.next.val: 341 | curr.next = curr.next.next 342 | else: 343 | curr = curr.next 344 | return head 345 | ``` 346 | ##### Time complexity: 347 | O(n) 348 | ##### Space complexity: 349 | O(1) 350 | ##### Notes: 351 | 1. Use a pointer to iterate through the linked list 352 | 2. Compare the current node with the next node 353 | 3. If they are the same, skip the next node 354 | 4. If they are different, move to the next node 355 | 5. Return the head of the modified linked list 356 | Make sure to handle edge cases such as an empty linked list. 357 | None 358 | None 359 | 360 | ### >> Comparison: 82 Remove Duplicates from Sorted List II [Medium] *VS* 83 Remove Duplicates from Sorted List [Easy] 361 | > Similarity distance: 0.3366 362 | ##### Similarities 363 | 364 | - Both questions involve removing duplicates from a sorted linked list. 365 | - Both questions have a similar input and output format. 366 | ##### Differences 367 | 368 | - Question 82 (Remove Duplicates from Sorted List II) removes all nodes that have duplicate values, while Question 83 (Remove Duplicates from Sorted List) removes only the duplicate nodes. 369 | - Question 82 requires removing all duplicates, even if they occur more than twice, while Question 83 removes duplicates that occur more than once. 370 | - Question 82 has a higher difficulty level (Medium) compared to Question 83 (Easy). 371 | ##### New Insights in 83 Remove Duplicates from Sorted List [Easy] 372 | 373 | - Question 82 requires keeping track of the previous node to remove duplicates, while Question 83 does not require this additional step. 374 | - Both questions can be solved using a similar approach of iterating through the linked list and removing duplicates. 375 | 376 | 377 | --- 378 | # 5. From 82 Remove Duplicates from Sorted List II [Medium] to 26 Remove Duplicates from Sorted Array [Easy] 379 | > Similarity Distance: 0.3591 380 | 381 | ### >> Reminder: 82 Remove Duplicates from Sorted List II [Medium] 382 | Given the head of a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Return the linked list sorted as well. 383 | ##### Optimal Python solution: 384 | ```python 385 | def deleteDuplicates(head): 386 | dummy = ListNode(0) 387 | dummy.next = head 388 | prev = dummy 389 | curr = head 390 | while curr: 391 | while curr.next and curr.val == curr.next.val: 392 | curr = curr.next 393 | if prev.next == curr: 394 | prev = prev.next 395 | else: 396 | prev.next = curr.next 397 | curr = curr.next 398 | return dummy.next 399 | ``` 400 | Remove duplicates from sorted linked list. 401 | 402 | ### >> 26 Remove Duplicates from Sorted Array [Easy] 403 | Given a sorted array nums, remove the duplicates in-place such that each element appears only once and returns the new length. 404 | ##### Sample input: 405 | nums = [1,1,2] 406 | ##### Sample output: 407 | 2 408 | 409 | ##### Questions to ask to clarify requirements: 410 | 411 | - Can we modify the original array? 412 | - What should be returned if the array is empty? 413 | - Can we assume the array is always sorted? 414 | 415 | ##### Optimal Python solution: 416 | ```python 417 | class Solution: 418 | def removeDuplicates(self, nums: List[int]) -> int: 419 | if not nums: 420 | return 0 421 | i = 0 422 | for j in range(1, len(nums)): 423 | if nums[j] != nums[i]: 424 | i += 1 425 | nums[i] = nums[j] 426 | return i + 1 427 | ``` 428 | ##### Time complexity: 429 | O(n) 430 | ##### Space complexity: 431 | O(1) 432 | ##### Notes: 433 | 434 | - Remove duplicates in-place 435 | - Use two pointers to track the current and next non-duplicate elements 436 | 437 | - Use two pointers to track the current and next non-duplicate elements 438 | - Update the array in-place by replacing the duplicate elements 439 | 440 | - Updating the array in-place while removing duplicates 441 | 442 | - Using additional data structures to track duplicates 443 | 444 | ### >> Comparison: 82 Remove Duplicates from Sorted List II [Medium] *VS* 26 Remove Duplicates from Sorted Array [Easy] 445 | > Similarity distance: 0.3591 446 | ##### Similarities 447 | 448 | - Both questions involve removing duplicates from a sorted list or array. 449 | - Both questions require modifying the original data structure. 450 | ##### Differences 451 | 452 | - Question 82 deals with a linked list, while question 26 deals with an array. 453 | - Question 82 allows duplicates to be present in the final list, while question 26 requires all elements to be unique. 454 | - Question 82 has a time complexity of O(n), while question 26 has a time complexity of O(n^2) if using the naive approach. 455 | - Question 82 requires the use of pointers to manipulate the linked list, while question 26 uses array manipulation techniques. 456 | ##### New Insights in 26 Remove Duplicates from Sorted Array [Easy] 457 | 458 | - Question 82 introduces the concept of linked list manipulation and pointer operations. 459 | - Question 26 highlights the importance of efficient array manipulation techniques to remove duplicates. 460 | 461 | 462 | --- 463 | # 6. From 82 Remove Duplicates from Sorted List II [Medium] to 316 Remove Duplicate Letters [Hard] 464 | > Similarity Distance: 0.3889 465 | 466 | ### >> Reminder: 82 Remove Duplicates from Sorted List II [Medium] 467 | Given the head of a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Return the linked list sorted as well. 468 | ##### Optimal Python solution: 469 | ```python 470 | def deleteDuplicates(head): 471 | dummy = ListNode(0) 472 | dummy.next = head 473 | prev = dummy 474 | curr = head 475 | while curr: 476 | while curr.next and curr.val == curr.next.val: 477 | curr = curr.next 478 | if prev.next == curr: 479 | prev = prev.next 480 | else: 481 | prev.next = curr.next 482 | curr = curr.next 483 | return dummy.next 484 | ``` 485 | Remove duplicates from sorted linked list. 486 | 487 | ### >> 316 Remove Duplicate Letters [Hard] 488 | Given a string s, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results. 489 | ##### Sample input: 490 | "bcabc" 491 | ##### Sample output: 492 | "abc" 493 | 494 | ##### Questions to ask to clarify requirements: 495 | 496 | - Can the input string contain spaces? 497 | - Can the input string contain special characters? 498 | - What is the maximum length of the input string? 499 | 500 | ##### Optimal Python solution: 501 | ```python 502 | def removeDuplicateLetters(s): 503 | counter = Counter(s) 504 | stack = [] 505 | visited = set() 506 | for char in s: 507 | counter[char] -= 1 508 | if char in visited: 509 | continue 510 | while stack and char < stack[-1] and counter[stack[-1]] > 0: 511 | visited.remove(stack.pop()) 512 | stack.append(char) 513 | visited.add(char) 514 | return ''.join(stack) 515 | ``` 516 | ##### Time complexity: 517 | O(n) 518 | ##### Space complexity: 519 | O(n) 520 | ##### Notes: 521 | 522 | - Use a stack to keep track of the characters in the result. 523 | - Remove characters from the stack if a smaller character is encountered later. 524 | - Keep track of the characters visited to avoid duplicates. 525 | 526 | - Keep track of the characters visited to avoid duplicates. 527 | - Remove characters from the stack if a smaller character is encountered later. 528 | 529 | - Removing characters from the stack if a smaller character is encountered later. 530 | - Keeping track of the characters visited to avoid duplicates. 531 | 532 | - Using a nested loop to compare each character with the characters visited and in the result. 533 | 534 | ### >> Comparison: 82 Remove Duplicates from Sorted List II [Medium] *VS* 316 Remove Duplicate Letters [Hard] 535 | > Similarity distance: 0.3889 536 | ##### Similarities 537 | 538 | - Both questions involve removing duplicates from a given list or string. 539 | - Both questions require maintaining the order of the remaining elements. 540 | - Both questions have a complexity requirement of O(n). 541 | ##### Differences 542 | 543 | - Question 82 deals with removing duplicates from a sorted linked list, while question 316 deals with removing duplicates from a string. 544 | - Question 82 allows removing all occurrences of a duplicate element, while question 316 requires keeping at least one occurrence of each duplicate element. 545 | - Question 82 has a complexity requirement of O(n), while question 316 has a complexity requirement of O(n^2). 546 | ##### New Insights in 316 Remove Duplicate Letters [Hard] 547 | 548 | - Question 82 can be solved using a two-pointer approach, where one pointer tracks the current element and the other pointer tracks the previous distinct element. 549 | - Question 316 can be solved using a greedy approach, where we maintain a stack to store the final result and keep track of the last occurrence of each character. 550 | 551 | -------------------------------------------------------------------------------- /intensive_study_guides/20231226_040350/leetcode_intensive_day_000006.md: -------------------------------------------------------------------------------- 1 | 2 | # Leetcode Intensive Tutorial Day 6 3 | > [Difficulty Score: 12] 4 | 5 | > [Version: 20231226_040350] 6 | 7 | > [Including this day, you had studied : 42 leetcode problems] 8 | 9 | 10 | ## Courses overview of the day 11 | 12 | - 190 Reverse Bits [Easy] 13 | - 7 Reverse Integer [Easy] 14 | - 371 Sum of Two Integers [Medium] 15 | - 289 Game of Life [Medium] 16 | - 29 Divide Two Integers [Medium] 17 | - 50 Pow(x, n) [Medium] 18 | - 372 Super Pow [Medium] 19 | 20 | #### Step by step 21 | 22 | - [1. From 190 Reverse Bits [Easy] to 7 Reverse Integer [Easy]](#1-from-190-reverse-bits-easy-to-7-reverse-integer-easy)) 23 | 24 | - [2. From 190 Reverse Bits [Easy] to 371 Sum of Two Integers [Medium]](#2-from-190-reverse-bits-easy-to-371-sum-of-two-integers-medium)) 25 | 26 | - [3. From 371 Sum of Two Integers [Medium] to 289 Game of Life [Medium]](#3-from-371-sum-of-two-integers-medium-to-289-game-of-life-medium)) 27 | 28 | - [4. From 371 Sum of Two Integers [Medium] to 29 Divide Two Integers [Medium]](#4-from-371-sum-of-two-integers-medium-to-29-divide-two-integers-medium)) 29 | 30 | - [5. From 371 Sum of Two Integers [Medium] to 50 Pow(x, n) [Medium]](#5-from-371-sum-of-two-integers-medium-to-50-powx,-n-medium)) 31 | 32 | - [6. From 50 Pow(x, n) [Medium] to 372 Super Pow [Medium]](#6-from-50-powx,-n-medium-to-372-super-pow-medium)) 33 | 34 | 35 | 36 | #### Summary 37 | 38 | 39 | - 371 Sum of Two Integers : The essence of this problem is to perform addition using bit manipulation without using the + and - operators. 40 | - 372 Super Pow : The essence of this problem is to calculate a^b % 1337 using modular arithmetic and exponentiation. 41 | - 50 Pow(x, n) : Calculate x raised to the power n using binary exponentiation. 42 | - 190 Reverse Bits : Reverse the bits of a 32 bits unsigned integer. 43 | - 7 Reverse Integer : Reverse the digits of an integer and handle edge cases. 44 | - 29 Divide Two Integers : Perform division without using multiplication, division, and mod operator. 45 | - 289 Game of Life : The essence of this problem is to update the board in-place without using extra space. This can be achieved by using bit manipulation to store the next state of each cell. 46 | > Similarity Diameter of these problems: 0.6051 47 | 48 | 49 | --- 50 | # 1. From 190 Reverse Bits [Easy] to 7 Reverse Integer [Easy] 51 | > Similarity Distance: 0.4619 52 | 53 | ### >> 190 Reverse Bits [Easy] 54 | Reverse bits of a given 32 bits unsigned integer. 55 | ##### Sample input: 56 | 43261596 57 | ##### Sample output: 58 | 964176192 59 | 60 | ##### Questions to ask to clarify requirements: 61 | What should be the behavior if the input is not a 32 bits unsigned integer? 62 | 63 | ##### Optimal Python solution: 64 | ```python 65 | def reverseBits(n): 66 | return int(bin(n)[2:].zfill(32)[::-1], 2) 67 | ``` 68 | ##### Time complexity: 69 | O(1) 70 | ##### Space complexity: 71 | O(1) 72 | ##### Notes: 73 | Convert the integer to binary representation, reverse the string, and convert it back to an integer. 74 | Use built-in functions to convert between binary and integer representations. 75 | Converting the integer to binary representation and reversing the string. 76 | None 77 | 78 | ### >> 7 Reverse Integer [Easy] 79 | Given a 32-bit signed integer, reverse digits of an integer. 80 | ##### Sample input: 81 | 123 82 | -123 83 | 120 84 | ##### Sample output: 85 | 321 86 | -321 87 | 21 88 | 89 | ##### Questions to ask to clarify requirements: 90 | What should be the output if the reversed integer overflows? 91 | 92 | ##### Optimal Python solution: 93 | ```python 94 | class Solution: 95 | def reverse(self, x: int) -> int: 96 | if x < 0: 97 | x = -int(str(-x)[::-1]) 98 | else: 99 | x = int(str(x)[::-1]) 100 | if x < -2**31 or x > 2**31 - 1: 101 | return 0 102 | return x 103 | ``` 104 | ##### Time complexity: 105 | O(log(x)) 106 | ##### Space complexity: 107 | O(1) 108 | ##### Notes: 109 | 1. Reverse the digits of the given integer. 110 | 2. Handle the case when the reversed integer overflows. 111 | 3. Handle the case when the input is a negative number. 112 | Use the modulo operator to extract the last digit of a number. 113 | Handling the case when the reversed integer overflows. 114 | Using string conversion to reverse the integer. 115 | 116 | ### >> Comparison: 190 Reverse Bits [Easy] *VS* 7 Reverse Integer [Easy] 117 | > Similarity distance: 0.4619 118 | ##### Similarities 119 | 120 | - Both questions involve reversing the bits or digits of a given number. 121 | - Both questions have an easy difficulty level. 122 | ##### Differences 123 | 124 | - Question 190 involves reversing the bits of a 32-bit unsigned integer, while question 7 involves reversing the digits of a signed integer. 125 | - Question 190 requires bitwise operations to reverse the bits, while question 7 requires arithmetic operations to reverse the digits. 126 | - Question 190 has a constraint on the input size (32-bit unsigned integer), while question 7 does not have any specific constraint on the input size. 127 | ##### New Insights in 7 Reverse Integer [Easy] 128 | 129 | - Question 190: Understanding bitwise operations and their applications in reversing bits. 130 | - Question 7: Handling integer overflow and underflow cases while reversing the digits. 131 | 132 | 133 | --- 134 | # 2. From 190 Reverse Bits [Easy] to 371 Sum of Two Integers [Medium] 135 | > Similarity Distance: 0.4638 136 | 137 | ### >> Reminder: 190 Reverse Bits [Easy] 138 | Reverse bits of a given 32 bits unsigned integer. 139 | ##### Optimal Python solution: 140 | ```python 141 | def reverseBits(n): 142 | return int(bin(n)[2:].zfill(32)[::-1], 2) 143 | ``` 144 | Reverse the bits of a 32 bits unsigned integer. 145 | 146 | ### >> 371 Sum of Two Integers [Medium] 147 | Calculate the sum of two integers without using the + and - operators. 148 | ##### Sample input: 149 | 1 150 | 2 151 | ##### Sample output: 152 | 3 153 | 154 | ##### Questions to ask to clarify requirements: 155 | Can the input integers be negative? 156 | 157 | ##### Optimal Python solution: 158 | ```python 159 | class Solution: 160 | def getSum(self, a: int, b: int) -> int: 161 | mask = 0xffffffff 162 | while b & mask: 163 | carry = (a & b) << 1 164 | a = a ^ b 165 | b = carry & mask 166 | return a if b > mask else a & mask 167 | ``` 168 | ##### Time complexity: 169 | O(1) 170 | ##### Space complexity: 171 | O(1) 172 | ##### Notes: 173 | 1. Use bit manipulation to perform addition 174 | 2. Handle negative integers by using a mask 175 | 3. Use a while loop to iterate until there is no carry 176 | Understand how bit manipulation works. 177 | Handling negative integers 178 | Using + and - operators 179 | 180 | ### >> Comparison: 190 Reverse Bits [Easy] *VS* 371 Sum of Two Integers [Medium] 181 | > Similarity distance: 0.4638 182 | ##### Similarities 183 | 184 | - Both questions involve bitwise operations. 185 | - Both questions require manipulating binary representations of numbers. 186 | ##### Differences 187 | 188 | - 190 Reverse Bits is an Easy level question, while 371 Sum of Two Integers is a Medium level question. 189 | - 190 Reverse Bits involves reversing the bits of a given 32-bit unsigned integer, while 371 Sum of Two Integers involves finding the sum of two integers without using the + or - operators. 190 | - 190 Reverse Bits requires shifting and bitwise operations, while 371 Sum of Two Integers requires bitwise operations and bit manipulation. 191 | - 190 Reverse Bits has a time complexity of O(1), while 371 Sum of Two Integers has a time complexity of O(log n). 192 | ##### New Insights in 371 Sum of Two Integers [Medium] 193 | 194 | - From 190 Reverse Bits, we can learn how to reverse the bits of a given number using bitwise operations. 195 | - From 371 Sum of Two Integers, we can learn how to perform addition of two integers using bitwise operations and bit manipulation. 196 | 197 | 198 | --- 199 | # 3. From 371 Sum of Two Integers [Medium] to 289 Game of Life [Medium] 200 | > Similarity Distance: 0.4004 201 | 202 | ### >> Reminder: 371 Sum of Two Integers [Medium] 203 | Calculate the sum of two integers without using the + and - operators. 204 | ##### Optimal Python solution: 205 | ```python 206 | class Solution: 207 | def getSum(self, a: int, b: int) -> int: 208 | mask = 0xffffffff 209 | while b & mask: 210 | carry = (a & b) << 1 211 | a = a ^ b 212 | b = carry & mask 213 | return a if b > mask else a & mask 214 | ``` 215 | The essence of this problem is to perform addition using bit manipulation without using the + and - operators. 216 | 217 | ### >> 289 Game of Life [Medium] 218 | Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules: 219 | 220 | Any live cell with fewer than two live neighbors dies, as if caused by under-population. 221 | Any live cell with two or three live neighbors lives on to the next generation. 222 | Any live cell with more than three live neighbors dies, as if by over-population. 223 | Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. 224 | Write a function to compute the next state (after one update) of the board given its current state. 225 | 226 | Follow up: 227 | Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some cells first and then use their updated values to update other cells. 228 | In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array. How would you address these problems? 229 | ##### Sample input: 230 | [[0,1,0],[0,0,1],[1,1,1],[0,0,0]] 231 | ##### Sample output: 232 | [[0,0,0],[1,0,1],[0,1,1],[0,1,0]] 233 | 234 | ##### Questions to ask to clarify requirements: 235 | What is the maximum size of the board? Can we assume the board is always rectangular? 236 | 237 | ##### Optimal Python solution: 238 | ```python 239 | def gameOfLife(board): 240 | m, n = len(board), len(board[0]) 241 | for i in range(m): 242 | for j in range(n): 243 | count = 0 244 | for I in range(max(i-1, 0), min(i+2, m)): 245 | for J in range(max(j-1, 0), min(j+2, n)): 246 | count += board[I][J] & 1 247 | if count == 3 or count - board[i][j] == 3: 248 | board[i][j] |= 2 249 | for i in range(m): 250 | for j in range(n): 251 | board[i][j] >>= 1 252 | ``` 253 | ##### Time complexity: 254 | O(m * n) 255 | ##### Space complexity: 256 | O(1) 257 | ##### Notes: 258 | 1. Use a nested loop to iterate through each cell in the board. 259 | 2. Count the number of live neighbors for each cell. 260 | 3. Update the cell based on the rules of the game. 261 | 4. Use bit manipulation to store the next state of each cell. 262 | 5. Shift the bits to get the final state of each cell. 263 | 1. Use bit manipulation to store the next state of each cell. 264 | 2. Shift the bits to get the final state of each cell. 265 | 3. Optimize the counting of live neighbors by only counting the live neighbors of the cells that are currently alive. 266 | The tricky part of this problem is updating the board in-place. We can use bit manipulation to store the next state of each cell without using extra space. 267 | Avoid using extra space to store the next state of each cell. 268 | 269 | ### >> Comparison: 371 Sum of Two Integers [Medium] *VS* 289 Game of Life [Medium] 270 | > Similarity distance: 0.4004 271 | ##### Similarities 272 | 273 | - Both questions are classified as medium difficulty. 274 | - Both questions involve manipulating and updating values in an array. 275 | - Both questions require understanding and implementing specific rules or algorithms. 276 | ##### Differences 277 | 278 | - Question 371 involves adding two integers without using the + or - operators. 279 | - Question 289 involves simulating the Game of Life using specific rules. 280 | - Question 371 focuses on bitwise operations, while question 289 focuses on array manipulation. 281 | - Question 371 requires understanding and implementing the concept of two's complement. 282 | - Question 289 requires understanding and implementing the concept of Conway's Game of Life. 283 | ##### New Insights in 289 Game of Life [Medium] 284 | 285 | - Question 371 teaches the concept of using bitwise operations to perform arithmetic operations. 286 | - Question 289 introduces the concept of simulating a cellular automaton using specific rules. 287 | - Both questions provide opportunities to improve problem-solving and algorithmic thinking skills. 288 | 289 | 290 | --- 291 | # 4. From 371 Sum of Two Integers [Medium] to 29 Divide Two Integers [Medium] 292 | > Similarity Distance: 0.4453 293 | 294 | ### >> Reminder: 371 Sum of Two Integers [Medium] 295 | Calculate the sum of two integers without using the + and - operators. 296 | ##### Optimal Python solution: 297 | ```python 298 | class Solution: 299 | def getSum(self, a: int, b: int) -> int: 300 | mask = 0xffffffff 301 | while b & mask: 302 | carry = (a & b) << 1 303 | a = a ^ b 304 | b = carry & mask 305 | return a if b > mask else a & mask 306 | ``` 307 | The essence of this problem is to perform addition using bit manipulation without using the + and - operators. 308 | 309 | ### >> 29 Divide Two Integers [Medium] 310 | Given two integers dividend and divisor, divide two integers without using multiplication, division, and mod operator. Return the quotient after dividing dividend by divisor. 311 | ##### Sample input: 312 | 10 313 | 3 314 | ##### Sample output: 315 | 3 316 | 317 | ##### Questions to ask to clarify requirements: 318 | What should be returned if the division overflows? Can we assume the inputs are valid integers? Can we use the built-in division operator? 319 | 320 | ##### Optimal Python solution: 321 | ```python 322 | class Solution: 323 | def divide(self, dividend: int, divisor: int) -> int: 324 | if dividend == -2**31 and divisor == -1: 325 | return 2**31 - 1 326 | sign = -1 if (dividend < 0) ^ (divisor < 0) else 1 327 | dividend, divisor = abs(dividend), abs(divisor) 328 | quotient = 0 329 | while dividend >= divisor: 330 | temp, i = divisor, 1 331 | while dividend >= temp: 332 | dividend -= temp 333 | quotient += i 334 | i <<= 1 335 | temp <<= 1 336 | return sign * quotient 337 | ``` 338 | ##### Time complexity: 339 | O(log(dividend/divisor)) 340 | ##### Space complexity: 341 | O(1) 342 | ##### Notes: 343 | 1. Use bit manipulation to perform division without using multiplication, division, and mod operator. 344 | 2. Handle edge cases such as overflow and minimum possible value of dividend. 345 | 3. Use a while loop to subtract the divisor from the dividend until the dividend is less than the divisor. 346 | 4. Keep track of the quotient by incrementing a counter variable. 347 | 5. Use bit shifting to multiply the divisor by 2 in each iteration. 348 | 1. Use bit manipulation to perform division without using multiplication, division, and mod operator. 349 | 2. Handle edge cases such as overflow and the minimum possible value of the dividend. 350 | 3. Use a while loop to subtract the divisor from the dividend until the dividend is less than the divisor. 351 | 4. Keep track of the quotient by incrementing a counter variable. 352 | 5. Use bit shifting to multiply the divisor by 2 in each iteration. 353 | Handling edge cases such as overflow and minimum possible value of dividend. 354 | Using multiplication, division, and mod operator. 355 | 356 | ### >> Comparison: 371 Sum of Two Integers [Medium] *VS* 29 Divide Two Integers [Medium] 357 | > Similarity distance: 0.4453 358 | ##### Similarities 359 | 360 | - Both questions are medium difficulty level. 361 | - Both questions involve mathematical operations. 362 | - Both questions require handling integer inputs and outputs. 363 | - Both questions involve manipulating bits in binary representation. 364 | ##### Differences 365 | 366 | - 371 Sum of Two Integers requires finding the sum of two integers without using the + or - operators. 367 | - 29 Divide Two Integers requires dividing two integers without using the / or % operators. 368 | - 371 Sum of Two Integers allows both positive and negative integers as inputs. 369 | - 29 Divide Two Integers only allows positive integers as inputs. 370 | - 371 Sum of Two Integers returns the sum of the two integers. 371 | - 29 Divide Two Integers returns the quotient of the two integers. 372 | ##### New Insights in 29 Divide Two Integers [Medium] 373 | 374 | - In 371 Sum of Two Integers, the bitwise XOR operation can be used to find the sum of two integers without carry. 375 | - In 29 Divide Two Integers, the bitwise shift operation can be used to perform division by powers of 2. 376 | 377 | 378 | --- 379 | # 5. From 371 Sum of Two Integers [Medium] to 50 Pow(x, n) [Medium] 380 | > Similarity Distance: 0.4786 381 | 382 | ### >> Reminder: 371 Sum of Two Integers [Medium] 383 | Calculate the sum of two integers without using the + and - operators. 384 | ##### Optimal Python solution: 385 | ```python 386 | class Solution: 387 | def getSum(self, a: int, b: int) -> int: 388 | mask = 0xffffffff 389 | while b & mask: 390 | carry = (a & b) << 1 391 | a = a ^ b 392 | b = carry & mask 393 | return a if b > mask else a & mask 394 | ``` 395 | The essence of this problem is to perform addition using bit manipulation without using the + and - operators. 396 | 397 | ### >> 50 Pow(x, n) [Medium] 398 | Implement pow(x, n), which calculates x raised to the power n (i.e., x^n). 399 | ##### Sample input: 400 | 2.00000, 10 401 | ##### Sample output: 402 | 1024.00000 403 | 404 | ##### Questions to ask to clarify requirements: 405 | 406 | - Can x be negative? 407 | - Can n be negative? 408 | - Can n be zero? 409 | 410 | ##### Optimal Python solution: 411 | ```python 412 | def myPow(x, n): 413 | if n == 0: 414 | return 1 415 | if n < 0: 416 | x = 1 / x 417 | n = -n 418 | result = 1 419 | while n > 0: 420 | if n % 2 == 1: 421 | result *= x 422 | x *= x 423 | n //= 2 424 | return result 425 | ``` 426 | ##### Time complexity: 427 | O(log n) 428 | ##### Space complexity: 429 | O(1) 430 | ##### Notes: 431 | 432 | - Use binary exponentiation to calculate x^n 433 | - Handle negative values of n by taking the reciprocal of x 434 | 435 | - Handle negative values of n by taking the reciprocal of x. 436 | - Handle large values of n by using binary exponentiation. 437 | 438 | - Handling negative values of n 439 | 440 | - Calculating x^n using a loop with n iterations 441 | 442 | ### >> Comparison: 371 Sum of Two Integers [Medium] *VS* 50 Pow(x, n) [Medium] 443 | > Similarity distance: 0.4786 444 | ##### Similarities 445 | 446 | - Both questions are classified as medium difficulty. 447 | - Both questions involve mathematical operations. 448 | - Both questions require implementing a solution using programming. 449 | ##### Differences 450 | 451 | - Question 371 involves adding two integers, while question 50 involves calculating the power of a number. 452 | - Question 371 requires implementing the addition operation without using the + or - operators, while question 50 requires implementing the power operation. 453 | - Question 371 has a constraint on the input range, while question 50 does not have any specific constraints. 454 | - Question 371 can be solved using bit manipulation, while question 50 can be solved using recursion or iteration. 455 | ##### New Insights in 50 Pow(x, n) [Medium] 456 | 457 | - Question 371 teaches us how to perform addition using bit manipulation. 458 | - Question 50 teaches us how to calculate the power of a number efficiently using recursion or iteration. 459 | 460 | 461 | --- 462 | # 6. From 50 Pow(x, n) [Medium] to 372 Super Pow [Medium] 463 | > Similarity Distance: 0.3941 464 | 465 | ### >> Reminder: 50 Pow(x, n) [Medium] 466 | Implement pow(x, n), which calculates x raised to the power n (i.e., x^n). 467 | ##### Optimal Python solution: 468 | ```python 469 | def myPow(x, n): 470 | if n == 0: 471 | return 1 472 | if n < 0: 473 | x = 1 / x 474 | n = -n 475 | result = 1 476 | while n > 0: 477 | if n % 2 == 1: 478 | result *= x 479 | x *= x 480 | n //= 2 481 | return result 482 | ``` 483 | Calculate x raised to the power n using binary exponentiation. 484 | 485 | ### >> 372 Super Pow [Medium] 486 | Calculate a^b % 1337 where a is a positive integer and b is an extremely large positive integer given in the form of an array. 487 | ##### Sample input: 488 | [2] 489 | [3] 490 | ##### Sample output: 491 | 8 492 | 493 | ##### Questions to ask to clarify requirements: 494 | What is the maximum value of b? 495 | 496 | ##### Optimal Python solution: 497 | ```python 498 | class Solution: 499 | def superPow(self, a: int, b: List[int]) -> int: 500 | result = 1 501 | for digit in b: 502 | result = pow(result, 10, 1337) * pow(a, digit, 1337) % 1337 503 | return result 504 | ``` 505 | ##### Time complexity: 506 | O(n) 507 | ##### Space complexity: 508 | O(1) 509 | ##### Notes: 510 | 1. Use modular arithmetic to calculate a^b % 1337 511 | 2. Break down b into its digits 512 | 3. Use the pow function to calculate the exponentiation 513 | Understand modular arithmetic and the pow function. 514 | Handling extremely large positive integers 515 | Using the ** operator 516 | 517 | ### >> Comparison: 50 Pow(x, n) [Medium] *VS* 372 Super Pow [Medium] 518 | > Similarity distance: 0.3941 519 | ##### Similarities 520 | 521 | - Both questions involve calculating the power of a number. 522 | - Both questions require handling large numbers and modular arithmetic. 523 | ##### Differences 524 | 525 | - Question 50 involves calculating the power of a number with a given exponent. 526 | - Question 372 involves calculating the power of a number with a given array of exponents. 527 | - Question 50 uses a simple iterative approach to calculate the power. 528 | - Question 372 requires using modular arithmetic and Euler's totient function. 529 | - Question 50 has a time complexity of O(n), where n is the exponent. 530 | - Question 372 has a time complexity of O(k), where k is the length of the array of exponents. 531 | ##### New Insights in 372 Super Pow [Medium] 532 | 533 | - Question 372 introduces the concept of modular arithmetic and its application in calculating powers. 534 | - Question 372 introduces the use of Euler's totient function to optimize the calculation of powers. 535 | 536 | -------------------------------------------------------------------------------- /intensive_study_guides/20231226_040350/leetcode_intensive_day_000010.md: -------------------------------------------------------------------------------- 1 | 2 | # Leetcode Intensive Tutorial Day 10 3 | > [Difficulty Score: 13] 4 | 5 | > [Version: 20231226_040350] 6 | 7 | > [Including this day, you had studied : 73 leetcode problems] 8 | 9 | 10 | ## Courses overview of the day 11 | 12 | - 598 Range Addition II [Easy] 13 | - 36 Valid Sudoku [Medium] 14 | - 551 Student Attendance Record I [Easy] 15 | - 275 H-Index II [Medium] 16 | - 274 H-Index [Medium] 17 | - 458 Poor Pigs [Hard] 18 | - 119 Pascal's Triangle II [Easy] 19 | 20 | #### Step by step 21 | 22 | - [1. From 598 Range Addition II [Easy] to 36 Valid Sudoku [Medium]](#1-from-598-range-addition-ii-easy-to-36-valid-sudoku-medium)) 23 | 24 | - [2. From 36 Valid Sudoku [Medium] to 551 Student Attendance Record I [Easy]](#2-from-36-valid-sudoku-medium-to-551-student-attendance-record-i-easy)) 25 | 26 | - [3. From 36 Valid Sudoku [Medium] to 275 H-Index II [Medium]](#3-from-36-valid-sudoku-medium-to-275-h-index-ii-medium)) 27 | 28 | - [4. From 275 H-Index II [Medium] to 274 H-Index [Medium]](#4-from-275-h-index-ii-medium-to-274-h-index-medium)) 29 | 30 | - [5. From 275 H-Index II [Medium] to 458 Poor Pigs [Hard]](#5-from-275-h-index-ii-medium-to-458-poor-pigs-hard)) 31 | 32 | - [6. From 598 Range Addition II [Easy] to 119 Pascal's Triangle II [Easy]](#6-from-598-range-addition-ii-easy-to-119-pascal's-triangle-ii-easy)) 33 | 34 | 35 | 36 | #### Summary 37 | 38 | 39 | - 598 Range Addition II : Increment the values in a matrix based on a list of operations and return the maximum value. 40 | - 551 Student Attendance Record I : Count the number of 'A' in the record and check if 'LLL' is present. 41 | - 36 Valid Sudoku : Check the validity of a Sudoku board by verifying each row, column, and sub-box. 42 | - 119 Pascal's Triangle II : The essence of this problem is to understand the relationship between Pascal's triangle and the binomial coefficient. 43 | - 458 Poor Pigs : Determining the minimum number of pigs needed to test all the buckets 44 | - 275 H-Index II : The essence of this problem is to find the h-index using binary search on a sorted array. 45 | - 274 H-Index : Computing the h-index of a researcher given an array of citations. 46 | > Similarity Diameter of these problems: 0.7102 47 | 48 | 49 | --- 50 | # 1. From 598 Range Addition II [Easy] to 36 Valid Sudoku [Medium] 51 | > Similarity Distance: 0.5366 52 | 53 | ### >> 598 Range Addition II [Easy] 54 | Given an m x n matrix M initialized with all 0's and a list of operations ops, increment the value of M[i][j] for each operation in ops. Return the maximum value in the matrix after performing all the operations. 55 | ##### Sample input: 56 | m = 3, n = 3 57 | ops = [[2,2],[3,3]] 58 | ##### Sample output: 59 | 4 60 | 61 | ##### Questions to ask to clarify requirements: 62 | 1. Can the list of operations be empty? 63 | 2. Can the dimensions of the matrix be 0? 64 | 3. Can the dimensions of the matrix be negative? 65 | 4. Can the dimensions of the matrix be greater than 10000? 66 | 5. Can the values in the list of operations be negative? 67 | 6. Can the values in the list of operations be greater than the dimensions of the matrix? 68 | 69 | ##### Optimal Python solution: 70 | ```python 71 | def maxCount(self, m: int, n: int, ops: List[List[int]]) -> int: 72 | min_row = m 73 | min_col = n 74 | for op in ops: 75 | min_row = min(min_row, op[0]) 76 | min_col = min(min_col, op[1]) 77 | return min_row * min_col 78 | ``` 79 | ##### Time complexity: 80 | O(n) 81 | ##### Space complexity: 82 | O(1) 83 | ##### Notes: 84 | 1. Use a loop to iterate through the list of operations. 85 | 2. Use variables to keep track of the minimum row and column values. 86 | 3. Return the product of the minimum row and column values. 87 | 1. Use variables to keep track of intermediate values. 88 | 2. Use a loop to iterate through a list or array. 89 | None 90 | None 91 | 92 | ### >> 36 Valid Sudoku [Medium] 93 | Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules: Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of the nine 3 x 3 sub-boxes of the grid must contain the digits 1-9 without repetition. 94 | ##### Sample input: 95 | [ 96 | ["5","3",".",".","7",".",".",".","."], 97 | ["6",".",".","1","9","5",".",".","."], 98 | [".","9","8",".",".",".",".","6","."], 99 | ["8",".",".",".","6",".",".",".","3"], 100 | ["4",".",".","8",".","3",".",".","1"], 101 | ["7",".",".",".","2",".",".",".","6"], 102 | [".","6",".",".",".",".","2","8","."], 103 | [".",".",".","4","1","9",".",".","5"], 104 | [".",".",".",".","8",".",".","7","9"] 105 | ] 106 | ##### Sample output: 107 | true 108 | 109 | ##### Questions to ask to clarify requirements: 110 | 111 | - Can the board contain characters other than digits and '.'? 112 | - Can the board have a size other than 9 x 9? 113 | - Can the board be empty? 114 | 115 | ##### Optimal Python solution: 116 | ```python 117 | def isValidSudoku(board): 118 | rows = [set() for _ in range(9)] 119 | cols = [set() for _ in range(9)] 120 | boxes = [set() for _ in range(9)] 121 | for i in range(9): 122 | for j in range(9): 123 | if board[i][j] != '.': 124 | num = int(board[i][j]) 125 | box_index = (i // 3) * 3 + j // 3 126 | if num in rows[i] or num in cols[j] or num in boxes[box_index]: 127 | return False 128 | rows[i].add(num) 129 | cols[j].add(num) 130 | boxes[box_index].add(num) 131 | return True 132 | ``` 133 | ##### Time complexity: 134 | O(1) 135 | ##### Space complexity: 136 | O(1) 137 | ##### Notes: 138 | 139 | - The Sudoku board is a 9 x 9 grid. 140 | - Each row, column, and 3 x 3 sub-box must contain the digits 1-9 without repetition. 141 | - The '.' character represents an empty cell. 142 | 143 | - Understand the rules of Sudoku. 144 | - Use sets to efficiently check for duplicate digits. 145 | - Iterate over each cell in the board and update the corresponding sets. 146 | 147 | - Checking the validity of each row, column, and sub-box. 148 | - Using sets to keep track of the digits in each row, column, and sub-box. 149 | 150 | - Checking the validity of each cell individually. 151 | - Using nested loops to iterate over the board. 152 | 153 | ### >> Comparison: 598 Range Addition II [Easy] *VS* 36 Valid Sudoku [Medium] 154 | > Similarity distance: 0.5366 155 | ##### Similarities 156 | 157 | - Both questions involve manipulating a 2D grid. 158 | - Both questions require checking for valid conditions. 159 | ##### Differences 160 | 161 | - 598 Range Addition II involves incrementing values in a submatrix. 162 | - 36 Valid Sudoku involves checking for duplicate values in rows, columns, and subgrids. 163 | ##### New Insights in 36 Valid Sudoku [Medium] 164 | 165 | - In 598 Range Addition II, the maximum value in the resulting grid is the number of times the most frequent coordinate appears. 166 | - In 36 Valid Sudoku, the valid condition is that each row, column, and subgrid must contain unique numbers from 1 to 9. 167 | 168 | 169 | --- 170 | # 2. From 36 Valid Sudoku [Medium] to 551 Student Attendance Record I [Easy] 171 | > Similarity Distance: 0.5726 172 | 173 | ### >> Reminder: 36 Valid Sudoku [Medium] 174 | Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules: Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of the nine 3 x 3 sub-boxes of the grid must contain the digits 1-9 without repetition. 175 | ##### Optimal Python solution: 176 | ```python 177 | def isValidSudoku(board): 178 | rows = [set() for _ in range(9)] 179 | cols = [set() for _ in range(9)] 180 | boxes = [set() for _ in range(9)] 181 | for i in range(9): 182 | for j in range(9): 183 | if board[i][j] != '.': 184 | num = int(board[i][j]) 185 | box_index = (i // 3) * 3 + j // 3 186 | if num in rows[i] or num in cols[j] or num in boxes[box_index]: 187 | return False 188 | rows[i].add(num) 189 | cols[j].add(num) 190 | boxes[box_index].add(num) 191 | return True 192 | ``` 193 | Check the validity of a Sudoku board by verifying each row, column, and sub-box. 194 | 195 | ### >> 551 Student Attendance Record I [Easy] 196 | You are given a string representing an attendance record for a student. The record only contains the following three characters: 'A' for absent, 'L' for late, and 'P' for present. Your task is to determine whether the student should be rewarded based on his attendance record. The student is rewarded if he doesn't have more than one 'A' (absent) or more than two continuous 'L' (late) in his record. 197 | ##### Sample input: 198 | PPALLP 199 | PPALLL 200 | APAPAP 201 | 202 | ##### Sample output: 203 | True 204 | False 205 | True 206 | 207 | 208 | ##### Questions to ask to clarify requirements: 209 | What are the possible characters in the attendance record? Can there be any other characters apart from 'A', 'L', and 'P'? 210 | 211 | ##### Optimal Python solution: 212 | ```python 213 | def checkRecord(s): 214 | return s.count('A') <= 1 and 'LLL' not in s 215 | 216 | ``` 217 | ##### Time complexity: 218 | O(n) 219 | ##### Space complexity: 220 | O(1) 221 | ##### Notes: 222 | 1. Count the number of 'A' in the record 223 | 2. Check if 'LLL' is present in the record 224 | 3. Return True if the conditions are satisfied, False otherwise 225 | Use the count() method to count the occurrences of a character in a string. 226 | None 227 | None 228 | 229 | ### >> Comparison: 36 Valid Sudoku [Medium] *VS* 551 Student Attendance Record I [Easy] 230 | > Similarity distance: 0.5726 231 | ##### Similarities 232 | 233 | - Both questions involve checking the validity of certain conditions. 234 | - Both questions require iterating over a 2D grid. 235 | - Both questions involve checking for duplicates in rows and columns. 236 | ##### Differences 237 | 238 | - Question 36 involves checking the validity of a Sudoku board, while question 551 involves checking the validity of a student's attendance record. 239 | - Question 36 requires additional checks for duplicates in each 3x3 sub-grid of the Sudoku board. 240 | - Question 551 requires checking for the presence of 'A' (absent) more than twice or 'LLL' (late) consecutively more than twice in the attendance record. 241 | ##### New Insights in 551 Student Attendance Record I [Easy] 242 | 243 | - Question 36: The use of a set data structure can be helpful in efficiently checking for duplicates. 244 | - Question 551: The use of regular expressions can simplify the checking of attendance records. 245 | 246 | 247 | --- 248 | # 3. From 36 Valid Sudoku [Medium] to 275 H-Index II [Medium] 249 | > Similarity Distance: 0.5875 250 | 251 | ### >> Reminder: 36 Valid Sudoku [Medium] 252 | Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules: Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of the nine 3 x 3 sub-boxes of the grid must contain the digits 1-9 without repetition. 253 | ##### Optimal Python solution: 254 | ```python 255 | def isValidSudoku(board): 256 | rows = [set() for _ in range(9)] 257 | cols = [set() for _ in range(9)] 258 | boxes = [set() for _ in range(9)] 259 | for i in range(9): 260 | for j in range(9): 261 | if board[i][j] != '.': 262 | num = int(board[i][j]) 263 | box_index = (i // 3) * 3 + j // 3 264 | if num in rows[i] or num in cols[j] or num in boxes[box_index]: 265 | return False 266 | rows[i].add(num) 267 | cols[j].add(num) 268 | boxes[box_index].add(num) 269 | return True 270 | ``` 271 | Check the validity of a Sudoku board by verifying each row, column, and sub-box. 272 | 273 | ### >> 275 H-Index II [Medium] 274 | Given an array of citations sorted in ascending order (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index. 275 | ##### Sample input: 276 | [0,1,3,5,6] 277 | ##### Sample output: 278 | 3 279 | 280 | ##### Questions to ask to clarify requirements: 281 | What is the definition of h-index? Can the input array be empty? 282 | 283 | ##### Optimal Python solution: 284 | ```python 285 | def hIndex(citations): 286 | n = len(citations) 287 | left, right = 0, n - 1 288 | while left <= right: 289 | mid = (left + right) // 2 290 | if citations[mid] == n - mid: 291 | return n - mid 292 | elif citations[mid] < n - mid: 293 | left = mid + 1 294 | else: 295 | right = mid - 1 296 | return n - left 297 | ``` 298 | ##### Time complexity: 299 | O(log n) 300 | ##### Space complexity: 301 | O(1) 302 | ##### Notes: 303 | 304 | - The h-index is defined as the maximum value h such that the researcher has at least h papers with h citations. 305 | - The input array is sorted in ascending order. 306 | - Use binary search to find the h-index. 307 | 308 | - Make sure to handle the edge case when the input array is empty. 309 | - Use the sorted property of the input array to optimize the search process. 310 | 311 | - Finding the h-index using binary search instead of linear search. 312 | - Handling the edge case when the input array is empty. 313 | 314 | - Using linear search to find the h-index. 315 | - Sorting the input array. 316 | 317 | ### >> Comparison: 36 Valid Sudoku [Medium] *VS* 275 H-Index II [Medium] 318 | > Similarity distance: 0.5875 319 | ##### Similarities 320 | 321 | - Both questions are classified as medium difficulty. 322 | - Both questions involve solving a problem related to numbers. 323 | - Both questions require checking for a specific condition in a given input. 324 | ##### Differences 325 | 326 | - Question 36 Valid Sudoku is about checking the validity of a Sudoku board. 327 | - Question 275 H-Index II is about finding the h-index of a researcher based on their citations. 328 | - Question 36 Valid Sudoku involves a 9x9 grid, while question 275 H-Index II involves an array of citations. 329 | - Question 36 Valid Sudoku requires checking for duplicate numbers in rows, columns, and 3x3 sub-grids. 330 | - Question 275 H-Index II requires finding the largest h-index that a researcher can have. 331 | - Question 36 Valid Sudoku has a time complexity of O(1) since the board size is fixed. 332 | - Question 275 H-Index II has a time complexity of O(log n) since it involves binary search. 333 | ##### New Insights in 275 H-Index II [Medium] 334 | 335 | - Question 36 Valid Sudoku teaches us how to check for duplicate numbers in a 2D grid. 336 | - Question 275 H-Index II teaches us how to find the h-index efficiently using binary search. 337 | 338 | 339 | --- 340 | # 4. From 275 H-Index II [Medium] to 274 H-Index [Medium] 341 | > Similarity Distance: 0.4353 342 | 343 | ### >> Reminder: 275 H-Index II [Medium] 344 | Given an array of citations sorted in ascending order (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index. 345 | ##### Optimal Python solution: 346 | ```python 347 | def hIndex(citations): 348 | n = len(citations) 349 | left, right = 0, n - 1 350 | while left <= right: 351 | mid = (left + right) // 2 352 | if citations[mid] == n - mid: 353 | return n - mid 354 | elif citations[mid] < n - mid: 355 | left = mid + 1 356 | else: 357 | right = mid - 1 358 | return n - left 359 | ``` 360 | The essence of this problem is to find the h-index using binary search on a sorted array. 361 | 362 | ### >> 274 H-Index [Medium] 363 | Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index. 364 | ##### Sample input: 365 | [3,0,6,1,5] 366 | ##### Sample output: 367 | 3 368 | 369 | ##### Questions to ask to clarify requirements: 370 | What is the definition of h-index? Can the input array be empty? 371 | 372 | ##### Optimal Python solution: 373 | ```python 374 | class Solution: 375 | def hIndex(self, citations: List[int]) -> int: 376 | n = len(citations) 377 | count = [0] * (n + 1) 378 | for citation in citations: 379 | if citation >= n: 380 | count[n] += 1 381 | else: 382 | count[citation] += 1 383 | total = 0 384 | for i in range(n, -1, -1): 385 | total += count[i] 386 | if total >= i: 387 | return i 388 | return 0 389 | ``` 390 | ##### Time complexity: 391 | O(n) 392 | ##### Space complexity: 393 | O(n) 394 | ##### Notes: 395 | 1. Count the number of papers with each citation count. 396 | 2. Iterate from the highest citation count to the lowest and find the maximum h-index. 397 | Use an array to count the number of papers with each citation count. 398 | Handling duplicate citations and empty input array. 399 | Sorting the input array. 400 | 401 | ### >> Comparison: 275 H-Index II [Medium] *VS* 274 H-Index [Medium] 402 | > Similarity distance: 0.4353 403 | ##### Similarities 404 | 405 | - Both questions are related to the H-Index concept. 406 | - Both questions have a medium difficulty level. 407 | ##### Differences 408 | 409 | - 275 H-Index II is a follow-up question to 274 H-Index. 410 | - 275 H-Index II is an optimized version of 274 H-Index. 411 | - 275 H-Index II has a different input format. 412 | - 275 H-Index II requires a more efficient solution. 413 | ##### New Insights in 274 H-Index [Medium] 414 | 415 | - The H-Index concept is about measuring the impact of a researcher's work. 416 | - The H-Index is the maximum number of papers with at least h citations. 417 | - The H-Index can be calculated using a binary search approach. 418 | 419 | 420 | --- 421 | # 5. From 275 H-Index II [Medium] to 458 Poor Pigs [Hard] 422 | > Similarity Distance: 0.5924 423 | 424 | ### >> Reminder: 275 H-Index II [Medium] 425 | Given an array of citations sorted in ascending order (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index. 426 | ##### Optimal Python solution: 427 | ```python 428 | def hIndex(citations): 429 | n = len(citations) 430 | left, right = 0, n - 1 431 | while left <= right: 432 | mid = (left + right) // 2 433 | if citations[mid] == n - mid: 434 | return n - mid 435 | elif citations[mid] < n - mid: 436 | left = mid + 1 437 | else: 438 | right = mid - 1 439 | return n - left 440 | ``` 441 | The essence of this problem is to find the h-index using binary search on a sorted array. 442 | 443 | ### >> 458 Poor Pigs [Hard] 444 | You are given 'buckets' of pig food and 'minutesToDie' minutes before the poisoned food kills the pig. You have 'minutesToTest' minutes to determine which bucket(s) contain the poisoned food. Each pig can be tested only once and dies within 'minutesToDie' minutes. How many pigs do you need to figure out which bucket(s) contain the poisoned food? 445 | ##### Sample input: 446 | buckets = 1000, minutesToDie = 15, minutesToTest = 60 447 | ##### Sample output: 448 | 5 449 | 450 | ##### Questions to ask to clarify requirements: 451 | 452 | - Can the number of buckets be zero? 453 | - Can the number of minutes be zero? 454 | 455 | ##### Optimal Python solution: 456 | ```python 457 | def poorPigs(buckets, minutesToDie, minutesToTest): 458 | pigs = 0 459 | while (minutesToTest // minutesToDie + 1) ** pigs < buckets: 460 | pigs += 1 461 | return pigs 462 | ``` 463 | ##### Time complexity: 464 | O(1) 465 | ##### Space complexity: 466 | O(1) 467 | ##### Notes: 468 | 469 | - Use logarithm to solve the problem 470 | - Each pig can test multiple buckets 471 | 472 | - Think about the problem in terms of the number of possible outcomes 473 | 474 | - Understanding the relationship between the number of pigs, buckets, and minutes 475 | 476 | - Using a loop 477 | 478 | ### >> Comparison: 275 H-Index II [Medium] *VS* 458 Poor Pigs [Hard] 479 | > Similarity distance: 0.5924 480 | ##### Similarities 481 | 482 | - Both questions are related to finding a specific value or condition. 483 | - Both questions require some form of analysis or calculation. 484 | - Both questions have a specific constraint or condition that needs to be considered. 485 | ##### Differences 486 | 487 | - 275 H-Index II is a medium difficulty question, while 458 Poor Pigs is a hard difficulty question. 488 | - 275 H-Index II involves finding the h-index of a researcher given a sorted array of citations, while 458 Poor Pigs involves finding the minimum number of pigs required to determine which bucket contains a poisoned substance. 489 | - 275 H-Index II requires a binary search approach, while 458 Poor Pigs requires a mathematical approach. 490 | ##### New Insights in 458 Poor Pigs [Hard] 491 | 492 | - From 275 H-Index II, we can learn how to efficiently find the h-index using a binary search approach. 493 | - From 458 Poor Pigs, we can learn how to solve a problem using mathematical analysis and optimization. 494 | 495 | 496 | --- 497 | # 6. From 598 Range Addition II [Easy] to 119 Pascal's Triangle II [Easy] 498 | > Similarity Distance: 0.5772 499 | 500 | ### >> Reminder: 598 Range Addition II [Easy] 501 | Given an m x n matrix M initialized with all 0's and a list of operations ops, increment the value of M[i][j] for each operation in ops. Return the maximum value in the matrix after performing all the operations. 502 | ##### Optimal Python solution: 503 | ```python 504 | def maxCount(self, m: int, n: int, ops: List[List[int]]) -> int: 505 | min_row = m 506 | min_col = n 507 | for op in ops: 508 | min_row = min(min_row, op[0]) 509 | min_col = min(min_col, op[1]) 510 | return min_row * min_col 511 | ``` 512 | Increment the values in a matrix based on a list of operations and return the maximum value. 513 | 514 | ### >> 119 Pascal's Triangle II [Easy] 515 | Given an integer rowIndex, return the rowIndexth row of the Pascal's triangle. 516 | ##### Sample input: 517 | 3 518 | ##### Sample output: 519 | [1,3,3,1] 520 | 521 | ##### Questions to ask to clarify requirements: 522 | What is the maximum value of rowIndex? Can we assume rowIndex is always non-negative? 523 | 524 | ##### Optimal Python solution: 525 | ```python 526 | class Solution: 527 | def getRow(self, rowIndex: int) -> List[int]: 528 | row = [1] 529 | for i in range(1, rowIndex + 1): 530 | row.append(row[i - 1] * (rowIndex - i + 1) // i) 531 | return row 532 | ``` 533 | ##### Time complexity: 534 | O(rowIndex) 535 | ##### Space complexity: 536 | O(rowIndex) 537 | ##### Notes: 538 | 1. The rowIndexth row of Pascal's triangle can be calculated using the previous row. 539 | 2. Each element in the row can be calculated using the formula C(n, k) = C(n-1, k-1) * (n-k+1) / k, where n is the rowIndex and k is the index of the element. 540 | 3. Start with the first row [1] and calculate each subsequent row using the formula. 541 | 4. Return the rowIndexth row. 542 | Use a single list to store the elements of the row and update the list in place. 543 | None 544 | None 545 | 546 | ### >> Comparison: 598 Range Addition II [Easy] *VS* 119 Pascal's Triangle II [Easy] 547 | > Similarity distance: 0.5772 548 | ##### Similarities 549 | 550 | - Both questions are classified as 'Easy' level. 551 | - Both questions involve manipulating arrays. 552 | - Both questions require understanding of basic mathematical operations. 553 | ##### Differences 554 | 555 | - Question 598 involves incrementing a rectangular region in a matrix. 556 | - Question 119 involves generating a specific row of Pascal's Triangle. 557 | - Question 598 requires finding the maximum value in the matrix after all operations. 558 | - Question 119 requires generating the row of Pascal's Triangle using only O(k) extra space. 559 | ##### New Insights in 119 Pascal's Triangle II [Easy] 560 | 561 | - Question 598 teaches us how to efficiently update a matrix using range addition. 562 | - Question 119 teaches us how to generate a specific row of Pascal's Triangle using only O(k) extra space. 563 | 564 | -------------------------------------------------------------------------------- /intensive_study_guides/20231226_040350/leetcode_intensive_day_000016.md: -------------------------------------------------------------------------------- 1 | 2 | # Leetcode Intensive Tutorial Day 16 3 | > [Difficulty Score: 15] 4 | 5 | > [Version: 20231226_040350] 6 | 7 | > [Including this day, you had studied : 121 leetcode problems] 8 | 9 | 10 | ## Courses overview of the day 11 | 12 | - 561 Array Partition I [Easy] 13 | - 215 Kth Largest Element in an Array [Medium] 14 | - 324 Wiggle Sort II [Medium] 15 | - 280 Wiggle Sort [Medium] 16 | - 179 Largest Number [Medium] 17 | - 522 Longest Uncommon Subsequence II [Medium] 18 | - 581 Shortest Unsorted Continuous Subarray [Medium] 19 | - 360 Sort Transformed Array [Medium] 20 | 21 | #### Step by step 22 | 23 | - [1. From 561 Array Partition I [Easy] to 215 Kth Largest Element in an Array [Medium]](#1-from-561-array-partition-i-easy-to-215-kth-largest-element-in-an-array-medium)) 24 | 25 | - [2. From 215 Kth Largest Element in an Array [Medium] to 324 Wiggle Sort II [Medium]](#2-from-215-kth-largest-element-in-an-array-medium-to-324-wiggle-sort-ii-medium)) 26 | 27 | - [3. From 561 Array Partition I [Easy] to 280 Wiggle Sort [Medium]](#3-from-561-array-partition-i-easy-to-280-wiggle-sort-medium)) 28 | 29 | - [4. From 280 Wiggle Sort [Medium] to 179 Largest Number [Medium]](#4-from-280-wiggle-sort-medium-to-179-largest-number-medium)) 30 | 31 | - [5. From 179 Largest Number [Medium] to 522 Longest Uncommon Subsequence II [Medium]](#5-from-179-largest-number-medium-to-522-longest-uncommon-subsequence-ii-medium)) 32 | 33 | - [6. From 522 Longest Uncommon Subsequence II [Medium] to 581 Shortest Unsorted Continuous Subarray [Medium]](#6-from-522-longest-uncommon-subsequence-ii-medium-to-581-shortest-unsorted-continuous-subarray-medium)) 34 | 35 | - [7. From 561 Array Partition I [Easy] to 360 Sort Transformed Array [Medium]](#7-from-561-array-partition-i-easy-to-360-sort-transformed-array-medium)) 36 | 37 | 38 | 39 | #### Summary 40 | 41 | 42 | - 581 Shortest Unsorted Continuous Subarray : Find the shortest unsorted subarray in an array. 43 | - 280 Wiggle Sort : The essence of this problem is to reorder the array in-place such that nums[0] <= nums[1] >= nums[2] <= nums[3].... 44 | - 522 Longest Uncommon Subsequence II : The essence of this question is to find the longest uncommon subsequence among a list of strings. 45 | - 215 Kth Largest Element in an Array : The essence of this problem is to find the kth largest element in an unsorted array. 46 | - 179 Largest Number : Sorting 47 | - 324 Wiggle Sort II : The essence of this problem is to reorder an unsorted array in a way that satisfies the wiggle sort condition. 48 | - 561 Array Partition I : The essence of this problem is to find the optimal pairing of elements to maximize the sum of the minimum elements in each pair. 49 | - 360 Sort Transformed Array : Apply a quadratic function to each element in a sorted array and return the sorted result. 50 | > Similarity Diameter of these problems: 0.6841 51 | 52 | 53 | --- 54 | # 1. From 561 Array Partition I [Easy] to 215 Kth Largest Element in an Array [Medium] 55 | > Similarity Distance: 0.4379 56 | 57 | ### >> 561 Array Partition I [Easy] 58 | Given an integer array nums of 2n integers, group these integers into n pairs (a1, b1), (a2, b2), ..., (an, bn) such that the sum of min(ai, bi) for all i is maximized. Return the maximized sum. 59 | ##### Sample input: 60 | [1,4,3,2] 61 | ##### Sample output: 62 | 4 63 | 64 | ##### Questions to ask to clarify requirements: 65 | What is the range of the input array? Can the array contain duplicates? 66 | 67 | ##### Optimal Python solution: 68 | ```python 69 | def arrayPairSum(nums): 70 | nums.sort() 71 | return sum(nums[::2]) 72 | ``` 73 | ##### Time complexity: 74 | O(nlogn) 75 | ##### Space complexity: 76 | O(1) 77 | ##### Notes: 78 | The sum of min(ai, bi) is maximized when the pairs are formed by adjacent elements in the sorted array. 79 | Use the built-in sort function in Python. 80 | None 81 | None 82 | 83 | ### >> 215 Kth Largest Element in an Array [Medium] 84 | Find the kth largest element in an unsorted array. 85 | ##### Sample input: 86 | [3,2,1,5,6,4] 87 | 2 88 | ##### Sample output: 89 | 5 90 | 91 | ##### Questions to ask to clarify requirements: 92 | What is the range of the input array? Can the array contain duplicates? What should be returned if k is larger than the length of the array? 93 | 94 | ##### Optimal Python solution: 95 | ```python 96 | def findKthLargest(nums, k): 97 | return sorted(nums)[-k] 98 | ``` 99 | ##### Time complexity: 100 | O(n log n) 101 | ##### Space complexity: 102 | O(1) 103 | ##### Notes: 104 | 1. Sort the array in descending order. 105 | 2. Return the kth element from the sorted array. 106 | Use the sorted() function in Python to sort the array in descending order. 107 | Using a heap data structure can improve the time complexity to O(n log k). 108 | Avoid using a brute force approach to sort the array. 109 | 110 | ### >> Comparison: 561 Array Partition I [Easy] *VS* 215 Kth Largest Element in an Array [Medium] 111 | > Similarity distance: 0.4379 112 | ##### Similarities 113 | 114 | - Both questions involve manipulating arrays. 115 | - Both questions require finding a specific element in the array. 116 | - Both questions have a time complexity of O(nlogn). 117 | ##### Differences 118 | 119 | - 561 Array Partition I involves dividing the array into pairs and summing the minimum value of each pair, while 215 Kth Largest Element in an Array involves finding the kth largest element in the array. 120 | - 561 Array Partition I has an input constraint of an even number of elements in the array, while 215 Kth Largest Element in an Array has no specific input constraint. 121 | - 561 Array Partition I has an output of the maximum sum of the minimum values of each pair, while 215 Kth Largest Element in an Array has an output of the kth largest element in the array. 122 | ##### New Insights in 215 Kth Largest Element in an Array [Medium] 123 | 124 | - 561 Array Partition I teaches us how to efficiently divide an array into pairs and find the sum of the minimum values. 125 | - 215 Kth Largest Element in an Array teaches us how to efficiently find the kth largest element in an array using a partitioning algorithm. 126 | 127 | 128 | --- 129 | # 2. From 215 Kth Largest Element in an Array [Medium] to 324 Wiggle Sort II [Medium] 130 | > Similarity Distance: 0.4925 131 | 132 | ### >> Reminder: 215 Kth Largest Element in an Array [Medium] 133 | Find the kth largest element in an unsorted array. 134 | ##### Optimal Python solution: 135 | ```python 136 | def findKthLargest(nums, k): 137 | return sorted(nums)[-k] 138 | ``` 139 | The essence of this problem is to find the kth largest element in an unsorted array. 140 | 141 | ### >> 324 Wiggle Sort II [Medium] 142 | Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3].... 143 | ##### Sample input: 144 | nums = [1, 5, 1, 1, 6, 4] 145 | nums = [1, 3, 2, 2, 3, 1] 146 | ##### Sample output: 147 | [1, 6, 1, 5, 1, 4] 148 | [2, 3, 1, 3, 1, 2] 149 | 150 | ##### Questions to ask to clarify requirements: 151 | Can the input array contain duplicate elements? Can the input array be empty? 152 | 153 | ##### Optimal Python solution: 154 | ```python 155 | class Solution: 156 | def wiggleSort(self, nums: List[int]) -> None: 157 | n = len(nums) 158 | sorted_nums = sorted(nums) 159 | mid = (n - 1) // 2 160 | nums[::2] = sorted_nums[:mid+1][::-1] 161 | nums[1::2] = sorted_nums[mid+1:][::-1] 162 | ``` 163 | ##### Time complexity: 164 | O(n log n) 165 | ##### Space complexity: 166 | O(n) 167 | ##### Notes: 168 | Sort the array in ascending order. 169 | Split the sorted array into two halves. 170 | Reverse each half. 171 | Interleave the two halves to get the wiggle sorted array. 172 | Understand the concept of wiggle sort and how it can be achieved by sorting and manipulating arrays. 173 | Optimize the solution by reversing the two halves of the sorted array instead of using additional space. 174 | Handle edge cases such as empty arrays and arrays with duplicate elements. 175 | Reversing the two halves of the sorted array to achieve the wiggle sort. 176 | Using a brute force approach to reorder the array. 177 | 178 | ### >> Comparison: 215 Kth Largest Element in an Array [Medium] *VS* 324 Wiggle Sort II [Medium] 179 | > Similarity distance: 0.4925 180 | ##### Similarities 181 | 182 | - Both questions are classified as medium difficulty. 183 | - Both questions involve manipulating an array. 184 | - Both questions require finding the kth largest element in the array. 185 | ##### Differences 186 | 187 | - 215 Kth Largest Element in an Array focuses on finding the kth largest element in the array. 188 | - 324 Wiggle Sort II focuses on rearranging the array in a specific order. 189 | - 215 Kth Largest Element in an Array uses a partitioning algorithm like QuickSelect. 190 | - 324 Wiggle Sort II uses a combination of sorting and rearranging techniques. 191 | ##### New Insights in 324 Wiggle Sort II [Medium] 192 | 193 | - 215 Kth Largest Element in an Array teaches us how to use the QuickSelect algorithm to efficiently find the kth largest element. 194 | - 324 Wiggle Sort II teaches us how to rearrange an array in a specific order to satisfy the wiggle sort property. 195 | 196 | 197 | --- 198 | # 3. From 561 Array Partition I [Easy] to 280 Wiggle Sort [Medium] 199 | > Similarity Distance: 0.4393 200 | 201 | ### >> Reminder: 561 Array Partition I [Easy] 202 | Given an integer array nums of 2n integers, group these integers into n pairs (a1, b1), (a2, b2), ..., (an, bn) such that the sum of min(ai, bi) for all i is maximized. Return the maximized sum. 203 | ##### Optimal Python solution: 204 | ```python 205 | def arrayPairSum(nums): 206 | nums.sort() 207 | return sum(nums[::2]) 208 | ``` 209 | The essence of this problem is to find the optimal pairing of elements to maximize the sum of the minimum elements in each pair. 210 | 211 | ### >> 280 Wiggle Sort [Medium] 212 | Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] <= nums[3].... 213 | ##### Sample input: 214 | [3,5,2,1,6,4] 215 | [1,2,3,4,5,6] 216 | ##### Sample output: 217 | [3,5,1,6,2,4] 218 | [1,3,2,5,4,6] 219 | 220 | ##### Questions to ask to clarify requirements: 221 | Can the array contain duplicate elements? 222 | 223 | ##### Optimal Python solution: 224 | ```python 225 | class Solution: 226 | def wiggleSort(self, nums: List[int]) -> None: 227 | for i in range(1, len(nums)): 228 | if (i % 2 == 1 and nums[i] < nums[i - 1]) or (i % 2 == 0 and nums[i] > nums[i - 1]): 229 | nums[i], nums[i - 1] = nums[i - 1], nums[i] 230 | ``` 231 | ##### Time complexity: 232 | O(n) 233 | ##### Space complexity: 234 | O(1) 235 | ##### Notes: 236 | 1. Iterate through the array and swap adjacent elements if they don't satisfy the wiggle sort condition. 237 | 2. Use the modulo operator to determine the position of the element in the array. 238 | 3. The time complexity of the solution is O(n), where n is the length of the array. 239 | 1. Use the modulo operator to determine the position of the element in the array. 240 | 2. Iterate through the array and swap adjacent elements if they don't satisfy the wiggle sort condition. 241 | None 242 | None 243 | 244 | ### >> Comparison: 561 Array Partition I [Easy] *VS* 280 Wiggle Sort [Medium] 245 | > Similarity distance: 0.4393 246 | ##### Similarities 247 | 248 | - Both questions involve manipulating arrays. 249 | - Both questions have a specific requirement for rearranging the elements of the array. 250 | ##### Differences 251 | 252 | - 561 Array Partition I: The goal is to divide the array into pairs and find the sum of the minimum element in each pair. 253 | - 280 Wiggle Sort: The goal is to rearrange the array such that nums[0] <= nums[1] >= nums[2] <= nums[3]... 254 | ##### New Insights in 280 Wiggle Sort [Medium] 255 | 256 | - 561 Array Partition I: The insight is to sort the array and then sum the elements at even indices. 257 | - 280 Wiggle Sort: The insight is to iterate through the array and swap elements to achieve the desired ordering. 258 | 259 | 260 | --- 261 | # 4. From 280 Wiggle Sort [Medium] to 179 Largest Number [Medium] 262 | > Similarity Distance: 0.4560 263 | 264 | ### >> Reminder: 280 Wiggle Sort [Medium] 265 | Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] <= nums[3].... 266 | ##### Optimal Python solution: 267 | ```python 268 | class Solution: 269 | def wiggleSort(self, nums: List[int]) -> None: 270 | for i in range(1, len(nums)): 271 | if (i % 2 == 1 and nums[i] < nums[i - 1]) or (i % 2 == 0 and nums[i] > nums[i - 1]): 272 | nums[i], nums[i - 1] = nums[i - 1], nums[i] 273 | ``` 274 | The essence of this problem is to reorder the array in-place such that nums[0] <= nums[1] >= nums[2] <= nums[3].... 275 | 276 | ### >> 179 Largest Number [Medium] 277 | Given a list of non-negative integers, arrange them such that they form the largest number. 278 | ##### Sample input: 279 | [10,2] 280 | ##### Sample output: 281 | "210" 282 | 283 | ##### Questions to ask to clarify requirements: 284 | Can the input list be empty? 285 | 286 | ##### Optimal Python solution: 287 | ```python 288 | def largestNumber(nums): 289 | nums = [str(num) for num in nums] 290 | nums.sort(key=lambda x: x*10, reverse=True) 291 | return str(int(''.join(nums))) 292 | ``` 293 | ##### Time complexity: 294 | O(nlogn) 295 | ##### Space complexity: 296 | O(n) 297 | ##### Notes: 298 | 299 | - Convert the numbers to strings 300 | - Sort the strings based on their concatenation 301 | - Join the sorted strings 302 | Use the key parameter of the sort function to define a custom sorting order 303 | Handling leading zeros 304 | Converting the numbers to integers 305 | 306 | ### >> Comparison: 280 Wiggle Sort [Medium] *VS* 179 Largest Number [Medium] 307 | > Similarity distance: 0.4560 308 | ##### Similarities 309 | 310 | - Both questions are classified as medium difficulty. 311 | - Both questions involve sorting. 312 | - Both questions require rearranging elements in a specific order. 313 | ##### Differences 314 | 315 | - 280 Wiggle Sort: The goal is to rearrange the array such that nums[0] <= nums[1] >= nums[2] <= nums[3]... 316 | - 179 Largest Number: The goal is to rearrange the array to form the largest possible number. 317 | ##### New Insights in 179 Largest Number [Medium] 318 | 319 | - 280 Wiggle Sort: We can solve this problem in linear time without using any extra space. 320 | - 179 Largest Number: We can use a custom comparator to sort the array in a specific order. 321 | 322 | 323 | --- 324 | # 5. From 179 Largest Number [Medium] to 522 Longest Uncommon Subsequence II [Medium] 325 | > Similarity Distance: 0.5737 326 | 327 | ### >> Reminder: 179 Largest Number [Medium] 328 | Given a list of non-negative integers, arrange them such that they form the largest number. 329 | ##### Optimal Python solution: 330 | ```python 331 | def largestNumber(nums): 332 | nums = [str(num) for num in nums] 333 | nums.sort(key=lambda x: x*10, reverse=True) 334 | return str(int(''.join(nums))) 335 | ``` 336 | Sorting 337 | 338 | ### >> 522 Longest Uncommon Subsequence II [Medium] 339 | Given a list of strings, you need to find the longest uncommon subsequence among them. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings. 340 | ##### Sample input: 341 | ["aba", "cdc", "aba"] 342 | ##### Sample output: 343 | 3 344 | 345 | ##### Questions to ask to clarify requirements: 346 | What is a subsequence of a string? 347 | 348 | ##### Optimal Python solution: 349 | ```python 350 | def findLUSlength(strs: List[str]) -> int: 351 | def is_subsequence(s: str, t: str) -> bool: 352 | i = 0 353 | for c in t: 354 | if i < len(s) and s[i] == c: 355 | i += 1 356 | return i == len(s) 357 | strs.sort(key=len, reverse=True) 358 | for i, s in enumerate(strs): 359 | if all(not is_subsequence(s, t) for j, t in enumerate(strs) if i != j): 360 | return len(s) 361 | return -1 362 | ``` 363 | ##### Time complexity: 364 | O(n^2 * m) 365 | ##### Space complexity: 366 | O(1) 367 | ##### Notes: 368 | 1. The longest uncommon subsequence is the longest string in the list if it is not a subsequence of any other string. 369 | 2. If all strings in the list are subsequences of each other, there is no uncommon subsequence. 370 | 3. The longest uncommon subsequence cannot be a subsequence of any other string. 371 | There is no specific programming tip for this question. 372 | There is no tricky part in this question. 373 | There is no specific thing to avoid in this question. 374 | 375 | ### >> Comparison: 179 Largest Number [Medium] *VS* 522 Longest Uncommon Subsequence II [Medium] 376 | > Similarity distance: 0.5737 377 | ##### Similarities 378 | 379 | - Both questions are classified as medium difficulty. 380 | - Both questions involve manipulating strings. 381 | - Both questions require finding the longest subsequence. 382 | - Both questions have multiple test cases. 383 | ##### Differences 384 | 385 | - Question 179 involves sorting the numbers in a specific way to form the largest number. 386 | - Question 522 involves finding the longest uncommon subsequence among a list of strings. 387 | - Question 179 has a time complexity of O(nlogn), while question 522 has a time complexity of O(n^2). 388 | - Question 179 has a space complexity of O(n), while question 522 has a space complexity of O(1). 389 | ##### New Insights in 522 Longest Uncommon Subsequence II [Medium] 390 | 391 | - Question 179 teaches us how to sort numbers in a custom way to form the largest number. 392 | - Question 522 teaches us how to find the longest uncommon subsequence among a list of strings efficiently. 393 | 394 | 395 | --- 396 | # 6. From 522 Longest Uncommon Subsequence II [Medium] to 581 Shortest Unsorted Continuous Subarray [Medium] 397 | > Similarity Distance: 0.5610 398 | 399 | ### >> Reminder: 522 Longest Uncommon Subsequence II [Medium] 400 | Given a list of strings, you need to find the longest uncommon subsequence among them. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings. 401 | ##### Optimal Python solution: 402 | ```python 403 | def findLUSlength(strs: List[str]) -> int: 404 | def is_subsequence(s: str, t: str) -> bool: 405 | i = 0 406 | for c in t: 407 | if i < len(s) and s[i] == c: 408 | i += 1 409 | return i == len(s) 410 | strs.sort(key=len, reverse=True) 411 | for i, s in enumerate(strs): 412 | if all(not is_subsequence(s, t) for j, t in enumerate(strs) if i != j): 413 | return len(s) 414 | return -1 415 | ``` 416 | The essence of this question is to find the longest uncommon subsequence among a list of strings. 417 | 418 | ### >> 581 Shortest Unsorted Continuous Subarray [Medium] 419 | Given an integer array nums, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order. 420 | 421 | Return the shortest such subarray and output its length. 422 | ##### Sample input: 423 | [2,6,4,8,10,9,15] 424 | ##### Sample output: 425 | 5 426 | 427 | ##### Questions to ask to clarify requirements: 428 | What is the maximum length of the input array? Can the array contain duplicates? 429 | 430 | ##### Optimal Python solution: 431 | ```python 432 | def findUnsortedSubarray(nums): 433 | sorted_nums = sorted(nums) 434 | start = len(nums) 435 | end = 0 436 | for i in range(len(nums)): 437 | if nums[i] != sorted_nums[i]: 438 | start = min(start, i) 439 | end = max(end, i) 440 | return end - start + 1 441 | ``` 442 | ##### Time complexity: 443 | O(nlogn) 444 | ##### Space complexity: 445 | O(n) 446 | ##### Notes: 447 | 1. Sort the array and compare it with the original array to find the start and end indices of the unsorted subarray. 448 | 2. Return the length of the subarray. 449 | Use the sorted() function to sort the array. 450 | None 451 | None 452 | 453 | ### >> Comparison: 522 Longest Uncommon Subsequence II [Medium] *VS* 581 Shortest Unsorted Continuous Subarray [Medium] 454 | > Similarity distance: 0.5610 455 | ##### Similarities 456 | 457 | - Both questions are classified as medium difficulty. 458 | - Both questions involve finding subsequences in an array. 459 | - Both questions require understanding of array manipulation. 460 | ##### Differences 461 | 462 | - 522 Longest Uncommon Subsequence II involves finding the longest uncommon subsequence among a list of strings. 463 | - 581 Shortest Unsorted Continuous Subarray involves finding the length of the shortest subarray that, when sorted, makes the entire array sorted. 464 | ##### New Insights in 581 Shortest Unsorted Continuous Subarray [Medium] 465 | 466 | - From 522 Longest Uncommon Subsequence II, we can learn how to efficiently compare and find uncommon subsequences among a list of strings. 467 | - From 581 Shortest Unsorted Continuous Subarray, we can learn how to identify the shortest unsorted subarray in an array. 468 | 469 | 470 | --- 471 | # 7. From 561 Array Partition I [Easy] to 360 Sort Transformed Array [Medium] 472 | > Similarity Distance: 0.5570 473 | 474 | ### >> Reminder: 561 Array Partition I [Easy] 475 | Given an integer array nums of 2n integers, group these integers into n pairs (a1, b1), (a2, b2), ..., (an, bn) such that the sum of min(ai, bi) for all i is maximized. Return the maximized sum. 476 | ##### Optimal Python solution: 477 | ```python 478 | def arrayPairSum(nums): 479 | nums.sort() 480 | return sum(nums[::2]) 481 | ``` 482 | The essence of this problem is to find the optimal pairing of elements to maximize the sum of the minimum elements in each pair. 483 | 484 | ### >> 360 Sort Transformed Array [Medium] 485 | Given a sorted array of integers nums and integer values a, b and c. Apply a quadratic function of the form f(x) = ax^2 + bx + c to each element x in the array. The returned array must be in sorted order. 486 | ##### Sample input: 487 | nums = [-4, -2, 2, 4], a = 1, b = 3, c = 5 488 | ##### Sample output: 489 | [3, 9, 15, 33] 490 | 491 | ##### Questions to ask to clarify requirements: 492 | 1. Can the array contain duplicate elements? 493 | 2. Can the values of a, b, and c be negative? 494 | 3. Can the array be empty? 495 | 496 | ##### Optimal Python solution: 497 | ```python 498 | class Solution: 499 | def sortTransformedArray(self, nums: List[int], a: int, b: int, c: int) -> List[int]: 500 | res = [] 501 | left, right = 0, len(nums) - 1 502 | while left <= right: 503 | left_val = a * nums[left] * nums[left] + b * nums[left] + c 504 | right_val = a * nums[right] * nums[right] + b * nums[right] + c 505 | if a >= 0: 506 | if left_val >= right_val: 507 | res.append(left_val) 508 | left += 1 509 | else: 510 | res.append(right_val) 511 | right -= 1 512 | else: 513 | if left_val <= right_val: 514 | res.append(left_val) 515 | left += 1 516 | else: 517 | res.append(right_val) 518 | right -= 1 519 | if a >= 0: 520 | return res[::-1] 521 | else: 522 | return res 523 | ``` 524 | ##### Time complexity: 525 | O(N) 526 | ##### Space complexity: 527 | O(1) 528 | ##### Notes: 529 | 1. Use two pointers to iterate from the start and end of the array. 530 | 2. Calculate the transformed value for each element using the quadratic function. 531 | 3. Append the transformed values to the result array in the correct order. 532 | 1. Use two pointers to iterate from the start and end of the array. 533 | 2. Calculate the transformed value for each element using the quadratic function. 534 | 3. Append the transformed values to the result array in the correct order. 535 | 1. Handling negative values of a. 536 | 2. Handling the case when a is equal to 0. 537 | 1. Sorting the array after applying the quadratic function. 538 | 2. Using additional data structures to store the transformed values. 539 | 540 | ### >> Comparison: 561 Array Partition I [Easy] *VS* 360 Sort Transformed Array [Medium] 541 | > Similarity distance: 0.5570 542 | ##### Similarities 543 | 544 | - Both questions involve manipulating arrays. 545 | - Both questions require sorting the array in some way. 546 | - Both questions have a time complexity of O(nlogn) for the sorting operation. 547 | ##### Differences 548 | 549 | - 561 Array Partition I involves dividing the array into pairs and summing the minimum value of each pair. 550 | - 360 Sort Transformed Array involves transforming the array elements using a quadratic function and then sorting the transformed array. 551 | ##### New Insights in 360 Sort Transformed Array [Medium] 552 | 553 | - 561 Array Partition I teaches us how to efficiently divide an array into pairs and find the sum of the minimum values. 554 | - 360 Sort Transformed Array teaches us how to transform array elements using a quadratic function and sort the transformed array. 555 | 556 | -------------------------------------------------------------------------------- /intensive_study_guides/20231226_040350/leetcode_intensive_day_000018.md: -------------------------------------------------------------------------------- 1 | 2 | # Leetcode Intensive Tutorial Day 18 3 | > [Difficulty Score: 15] 4 | 5 | > [Version: 20231226_040350] 6 | 7 | > [Including this day, you had studied : 137 leetcode problems] 8 | 9 | 10 | ## Courses overview of the day 11 | 12 | - 169 Majority Element [Easy] 13 | - 229 Majority Element II [Medium] 14 | - 470 Implement Rand10() Using Rand7() [Medium] 15 | - 386 Lexicographical Numbers [Medium] 16 | - 60 Permutation Sequence [Medium] 17 | - 31 Next Permutation [Medium] 18 | - 262 Trips and Users [Hard] 19 | 20 | #### Step by step 21 | 22 | - [1. From 169 Majority Element [Easy] to 229 Majority Element II [Medium]](#1-from-169-majority-element-easy-to-229-majority-element-ii-medium)) 23 | 24 | - [2. From 229 Majority Element II [Medium] to 470 Implement Rand10() Using Rand7() [Medium]](#2-from-229-majority-element-ii-medium-to-470-implement-rand10-using-rand7-medium)) 25 | 26 | - [3. From 470 Implement Rand10() Using Rand7() [Medium] to 386 Lexicographical Numbers [Medium]](#3-from-470-implement-rand10-using-rand7-medium-to-386-lexicographical-numbers-medium)) 27 | 28 | - [4. From 386 Lexicographical Numbers [Medium] to 60 Permutation Sequence [Medium]](#4-from-386-lexicographical-numbers-medium-to-60-permutation-sequence-medium)) 29 | 30 | - [5. From 60 Permutation Sequence [Medium] to 31 Next Permutation [Medium]](#5-from-60-permutation-sequence-medium-to-31-next-permutation-medium)) 31 | 32 | - [6. From 229 Majority Element II [Medium] to 262 Trips and Users [Hard]](#6-from-229-majority-element-ii-medium-to-262-trips-and-users-hard)) 33 | 34 | 35 | 36 | #### Summary 37 | 38 | 39 | - 470 Implement Rand10() Using Rand7() : Generating a random number in a specific range using a random number generator with a different range. 40 | - 60 Permutation Sequence : The essence of this problem is to generate all permutations and select the kth permutation. 41 | - 386 Lexicographical Numbers : The essence of this problem is to generate the numbers from 1 to n in lexicographical order. 42 | - 229 Majority Element II : The essence of this problem is to find the majority elements that appear more than ⌊n/3⌋ times in an array. 43 | - 262 Trips and Users : Get the banned users based on the Trips and Users tables. 44 | - 169 Majority Element : The majority element appears more than n/2 times in the array. 45 | - 31 Next Permutation : The essence of the problem is to find the next permutation of a given list of numbers. 46 | > Similarity Diameter of these problems: 0.7398 47 | 48 | 49 | --- 50 | # 1. From 169 Majority Element [Easy] to 229 Majority Element II [Medium] 51 | > Similarity Distance: 0.2933 52 | 53 | ### >> 169 Majority Element [Easy] 54 | Given an array nums of size n, return the majority element. 55 | ##### Sample input: 56 | [3,2,3] 57 | ##### Sample output: 58 | 3 59 | 60 | ##### Questions to ask to clarify requirements: 61 | What is the definition of majority element? Can the array be empty? 62 | 63 | ##### Optimal Python solution: 64 | ```python 65 | def majorityElement(nums): 66 | count = 0 67 | candidate = None 68 | for num in nums: 69 | if count == 0: 70 | candidate = num 71 | count += (1 if num == candidate else -1) 72 | return candidate 73 | ``` 74 | ##### Time complexity: 75 | O(n) 76 | ##### Space complexity: 77 | O(1) 78 | ##### Notes: 79 | The majority element appears more than n/2 times in the array. 80 | None 81 | None 82 | None 83 | 84 | ### >> 229 Majority Element II [Medium] 85 | Given an integer array of size n, find all elements that appear more than ⌊n/3⌋ times. 86 | ##### Sample input: 87 | [3,2,3] 88 | ##### Sample output: 89 | [3] 90 | 91 | ##### Questions to ask to clarify requirements: 92 | What is the range of the input array? Can the array be empty? 93 | 94 | ##### Optimal Python solution: 95 | ```python 96 | class Solution: 97 | def majorityElement(self, nums: List[int]) -> List[int]: 98 | count1, count2, candidate1, candidate2 = 0, 0, 0, 1 99 | for num in nums: 100 | if num == candidate1: 101 | count1 += 1 102 | elif num == candidate2: 103 | count2 += 1 104 | elif count1 == 0: 105 | candidate1, count1 = num, 1 106 | elif count2 == 0: 107 | candidate2, count2 = num, 1 108 | else: 109 | count1, count2 = count1 - 1, count2 - 1 110 | return [n for n in (candidate1, candidate2) if nums.count(n) > len(nums) // 3] 111 | ``` 112 | ##### Time complexity: 113 | O(n) 114 | ##### Space complexity: 115 | O(1) 116 | ##### Notes: 117 | 1. Use the voting algorithm to find the majority elements. 118 | 2. The majority elements must appear more than ⌊n/3⌋ times. 119 | Understand the voting algorithm and how it guarantees finding the majority elements. 120 | The voting algorithm requires two counters and two candidates to keep track of the majority elements. 121 | Using a hashmap to count the occurrences of each element. 122 | 123 | ### >> Comparison: 169 Majority Element [Easy] *VS* 229 Majority Element II [Medium] 124 | > Similarity distance: 0.2933 125 | ##### Similarities 126 | 127 | - Both questions are about finding the majority element in an array. 128 | - The majority element is the element that appears more than ⌊n/2⌋ times in the array. 129 | - Both questions require finding the majority element in linear time and constant space. 130 | ##### Differences 131 | 132 | - 169 Majority Element [Easy] requires finding the majority element that appears more than ⌊n/2⌋ times. 133 | - 229 Majority Element II [Medium] requires finding all the majority elements that appear more than ⌊n/3⌋ times. 134 | - 169 Majority Element [Easy] can assume that the majority element always exists. 135 | - 229 Majority Element II [Medium] needs to handle the case where there may be no majority element. 136 | ##### New Insights in 229 Majority Element II [Medium] 137 | 138 | - 169 Majority Element [Easy] can be solved using the Boyer-Moore Voting Algorithm. 139 | - 229 Majority Element II [Medium] can be solved using the Boyer-Moore Voting Algorithm with a modification. 140 | 141 | 142 | --- 143 | # 2. From 229 Majority Element II [Medium] to 470 Implement Rand10() Using Rand7() [Medium] 144 | > Similarity Distance: 0.5740 145 | 146 | ### >> Reminder: 229 Majority Element II [Medium] 147 | Given an integer array of size n, find all elements that appear more than ⌊n/3⌋ times. 148 | ##### Optimal Python solution: 149 | ```python 150 | class Solution: 151 | def majorityElement(self, nums: List[int]) -> List[int]: 152 | count1, count2, candidate1, candidate2 = 0, 0, 0, 1 153 | for num in nums: 154 | if num == candidate1: 155 | count1 += 1 156 | elif num == candidate2: 157 | count2 += 1 158 | elif count1 == 0: 159 | candidate1, count1 = num, 1 160 | elif count2 == 0: 161 | candidate2, count2 = num, 1 162 | else: 163 | count1, count2 = count1 - 1, count2 - 1 164 | return [n for n in (candidate1, candidate2) if nums.count(n) > len(nums) // 3] 165 | ``` 166 | The essence of this problem is to find the majority elements that appear more than ⌊n/3⌋ times in an array. 167 | 168 | ### >> 470 Implement Rand10() Using Rand7() [Medium] 169 | Implement the rand10() function using the rand7() function. 170 | ##### Sample input: 171 | N/A 172 | ##### Sample output: 173 | N/A 174 | 175 | ##### Questions to ask to clarify requirements: 176 | 177 | - What is the range of numbers that rand10() should generate? 178 | - Can we assume that rand7() is a perfect random number generator? 179 | 180 | ##### Optimal Python solution: 181 | ```python 182 | class Solution: 183 | def rand10(self) -> int: 184 | while True: 185 | num = (rand7() - 1) * 7 + rand7() 186 | if num <= 40: 187 | return num % 10 + 1 188 | ``` 189 | ##### Time complexity: 190 | O(1) on average 191 | ##### Space complexity: 192 | O(1) 193 | ##### Notes: 194 | 195 | - The solution uses rejection sampling to generate a random number in the range 1 to 10. 196 | - The probability of each number in the range 1 to 10 is equal. 197 | - The solution discards numbers greater than 40 and uses modular arithmetic to map the remaining numbers to the range 1 to 10. 198 | 199 | - Understand the probability distribution of the generated numbers. 200 | - Consider the worst case scenario when analyzing the time complexity. 201 | 202 | - Using rejection sampling to generate a random number in a specific range 203 | 204 | - Using a loop to generate random numbers until a desired range is obtained 205 | 206 | ### >> Comparison: 229 Majority Element II [Medium] *VS* 470 Implement Rand10() Using Rand7() [Medium] 207 | > Similarity distance: 0.5740 208 | ##### Similarities 209 | 210 | - Both questions are classified as medium difficulty. 211 | - Both questions involve finding a majority element. 212 | - Both questions require implementing a specific function. 213 | ##### Differences 214 | 215 | - Question 229 involves finding the majority element(s) that appear more than ⌊n/3⌋ times in an array. 216 | - Question 470 involves implementing a function Rand10() using another function Rand7(). 217 | - Question 229 requires a linear time complexity solution, while question 470 does not specify any specific time complexity requirement. 218 | ##### New Insights in 470 Implement Rand10() Using Rand7() [Medium] 219 | 220 | - Question 229: The Boyer-Moore Voting Algorithm can be used to find the majority element(s) in linear time. 221 | - Question 470: The rejection sampling technique can be used to implement Rand10() using Rand7(). 222 | 223 | 224 | --- 225 | # 3. From 470 Implement Rand10() Using Rand7() [Medium] to 386 Lexicographical Numbers [Medium] 226 | > Similarity Distance: 0.4944 227 | 228 | ### >> Reminder: 470 Implement Rand10() Using Rand7() [Medium] 229 | Implement the rand10() function using the rand7() function. 230 | ##### Optimal Python solution: 231 | ```python 232 | class Solution: 233 | def rand10(self) -> int: 234 | while True: 235 | num = (rand7() - 1) * 7 + rand7() 236 | if num <= 40: 237 | return num % 10 + 1 238 | ``` 239 | Generating a random number in a specific range using a random number generator with a different range. 240 | 241 | ### >> 386 Lexicographical Numbers [Medium] 242 | Given an integer n, return 1 - n in lexicographical order. 243 | ##### Sample input: 244 | 13 245 | ##### Sample output: 246 | [1,10,11,12,13,2,3,4,5,6,7,8,9] 247 | 248 | ##### Questions to ask to clarify requirements: 249 | What should be the output format? Can the input be negative? 250 | 251 | ##### Optimal Python solution: 252 | ```python 253 | class Solution: 254 | def lexicalOrder(self, n: int) -> List[int]: 255 | res = [] 256 | curr = 1 257 | for _ in range(n): 258 | res.append(curr) 259 | if curr * 10 <= n: 260 | curr *= 10 261 | elif curr % 10 != 9 and curr + 1 <= n: 262 | curr += 1 263 | else: 264 | while (curr // 10) % 10 == 9: 265 | curr //= 10 266 | curr = curr // 10 + 1 267 | return res 268 | ``` 269 | ##### Time complexity: 270 | O(n) 271 | ##### Space complexity: 272 | O(n) 273 | ##### Notes: 274 | 1. Use a list to store the lexicographically ordered numbers 275 | 2. Use a variable to keep track of the current number 276 | 3. Use a loop to generate the numbers in lexicographical order 277 | Use a loop to generate the numbers in lexicographical order. Handle the special cases when the current number ends with 9. 278 | Determining the next number in lexicographical order 279 | Using recursion 280 | 281 | ### >> Comparison: 470 Implement Rand10() Using Rand7() [Medium] *VS* 386 Lexicographical Numbers [Medium] 282 | > Similarity distance: 0.4944 283 | ##### Similarities 284 | 285 | - Both questions are classified as medium difficulty. 286 | - Both questions involve generating random numbers. 287 | - Both questions require implementing a function. 288 | - Both questions have a specific input-output relationship. 289 | ##### Differences 290 | 291 | - Question 470 involves implementing the Rand10() function using the Rand7() function. 292 | - Question 386 involves generating lexicographically sorted numbers from 1 to n. 293 | ##### New Insights in 386 Lexicographical Numbers [Medium] 294 | 295 | - Question 470 teaches us how to generate a random number between 1 and 10 using a random number generator that generates numbers between 1 and 7. 296 | - Question 386 teaches us how to generate lexicographically sorted numbers using a specific algorithm. 297 | 298 | 299 | --- 300 | # 4. From 386 Lexicographical Numbers [Medium] to 60 Permutation Sequence [Medium] 301 | > Similarity Distance: 0.5097 302 | 303 | ### >> Reminder: 386 Lexicographical Numbers [Medium] 304 | Given an integer n, return 1 - n in lexicographical order. 305 | ##### Optimal Python solution: 306 | ```python 307 | class Solution: 308 | def lexicalOrder(self, n: int) -> List[int]: 309 | res = [] 310 | curr = 1 311 | for _ in range(n): 312 | res.append(curr) 313 | if curr * 10 <= n: 314 | curr *= 10 315 | elif curr % 10 != 9 and curr + 1 <= n: 316 | curr += 1 317 | else: 318 | while (curr // 10) % 10 == 9: 319 | curr //= 10 320 | curr = curr // 10 + 1 321 | return res 322 | ``` 323 | The essence of this problem is to generate the numbers from 1 to n in lexicographical order. 324 | 325 | ### >> 60 Permutation Sequence [Medium] 326 | Given n and k, return the kth permutation sequence of the numbers from 1 to n. 327 | ##### Sample input: 328 | 3 329 | 3 330 | 331 | ##### Sample output: 332 | 213 333 | 334 | 335 | ##### Questions to ask to clarify requirements: 336 | What should be the maximum value of n and k? Can the input be negative? 337 | 338 | ##### Optimal Python solution: 339 | ```python 340 | class Solution: 341 | def getPermutation(self, n: int, k: int) -> str: 342 | nums = [str(i) for i in range(1, n + 1)] 343 | result = '' 344 | k -= 1 345 | while n > 0: 346 | n -= 1 347 | index, k = divmod(k, math.factorial(n)) 348 | result += nums[index] 349 | nums.pop(index) 350 | return result 351 | 352 | ``` 353 | ##### Time complexity: 354 | O(n^2) 355 | ##### Space complexity: 356 | O(n) 357 | ##### Notes: 358 | 1. Generate all permutations of the numbers from 1 to n. 359 | 2. Find the kth permutation by dividing k by (n-1) factorial and using the quotient as the index to select the next number. 360 | 3. Remove the selected number from the list of available numbers and repeat the process until all numbers are used. 361 | None 362 | None 363 | None 364 | 365 | ### >> Comparison: 386 Lexicographical Numbers [Medium] *VS* 60 Permutation Sequence [Medium] 366 | > Similarity distance: 0.5097 367 | ##### Similarities 368 | 369 | - Both questions are classified as medium difficulty. 370 | - Both questions involve permutations or combinations. 371 | - Both questions require understanding of lexicographical order. 372 | ##### Differences 373 | 374 | - Question 386 involves generating all lexicographical numbers up to a given integer n. 375 | - Question 60 involves finding the kth permutation sequence of a given set of numbers. 376 | ##### New Insights in 60 Permutation Sequence [Medium] 377 | 378 | - Question 386 teaches us how to generate lexicographical numbers using depth-first search (DFS). 379 | - Question 60 teaches us how to find the kth permutation sequence using factorials and backtracking. 380 | 381 | 382 | --- 383 | # 5. From 60 Permutation Sequence [Medium] to 31 Next Permutation [Medium] 384 | > Similarity Distance: 0.4914 385 | 386 | ### >> Reminder: 60 Permutation Sequence [Medium] 387 | Given n and k, return the kth permutation sequence of the numbers from 1 to n. 388 | ##### Optimal Python solution: 389 | ```python 390 | class Solution: 391 | def getPermutation(self, n: int, k: int) -> str: 392 | nums = [str(i) for i in range(1, n + 1)] 393 | result = '' 394 | k -= 1 395 | while n > 0: 396 | n -= 1 397 | index, k = divmod(k, math.factorial(n)) 398 | result += nums[index] 399 | nums.pop(index) 400 | return result 401 | 402 | ``` 403 | The essence of this problem is to generate all permutations and select the kth permutation. 404 | 405 | ### >> 31 Next Permutation [Medium] 406 | Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. 407 | ##### Sample input: 408 | [1,2,3] 409 | ##### Sample output: 410 | [1,3,2] 411 | 412 | ##### Questions to ask to clarify requirements: 413 | 414 | - What is the definition of lexicographically next greater permutation? 415 | - Can the input contain duplicate numbers? 416 | 417 | ##### Optimal Python solution: 418 | ```python 419 | def nextPermutation(nums): 420 | i = j = len(nums)-1 421 | while i > 0 and nums[i-1] >= nums[i]: 422 | i -= 1 423 | if i == 0: 424 | nums.reverse() 425 | return 426 | k = i - 1 427 | while nums[j] <= nums[k]: 428 | j -= 1 429 | nums[k], nums[j] = nums[j], nums[k] 430 | l, r = k+1, len(nums)-1 431 | while l < r: 432 | nums[l], nums[r] = nums[r], nums[l] 433 | l += 1 434 | r -= 1 435 | ``` 436 | ##### Time complexity: 437 | O(n) 438 | ##### Space complexity: 439 | O(1) 440 | ##### Notes: 441 | 442 | - The next permutation is the smallest possible permutation that is greater than the current permutation. 443 | - If no next permutation is possible, rearrange the numbers to the lowest possible order (sorted in ascending order). 444 | 445 | - Use two pointers to find the first pair of adjacent numbers in descending order. 446 | - Use another pointer to find the next larger number to the left of the smaller number. 447 | - Use two pointers to reverse the numbers to the right of the smaller number. 448 | 449 | - Finding the next permutation involves finding the first pair of adjacent numbers in descending order. 450 | - To find the next permutation, we need to swap the smaller number with the next larger number to its right, and then reverse the numbers to the right of the smaller number. 451 | 452 | - Avoid using additional space. 453 | - Avoid using sorting algorithms. 454 | 455 | ### >> Comparison: 60 Permutation Sequence [Medium] *VS* 31 Next Permutation [Medium] 456 | > Similarity distance: 0.4914 457 | ##### Similarities 458 | 459 | - Both questions involve permutations of a given set of numbers. 460 | - Both questions have a medium difficulty level. 461 | ##### Differences 462 | 463 | - The '60 Permutation Sequence' question asks for the kth permutation of a given set of numbers, while the '31 Next Permutation' question asks for the next permutation in lexicographical order. 464 | - The '60 Permutation Sequence' question requires the use of factorials and mathematical calculations to find the kth permutation, while the '31 Next Permutation' question requires rearranging the given set of numbers to find the next permutation. 465 | - The '60 Permutation Sequence' question has a fixed set of numbers, while the '31 Next Permutation' question allows any permutation of a given set of numbers. 466 | ##### New Insights in 31 Next Permutation [Medium] 467 | 468 | - The '60 Permutation Sequence' question introduces the concept of finding the kth permutation using factorials and mathematical calculations. 469 | - The '31 Next Permutation' question introduces the concept of finding the next permutation in lexicographical order by rearranging the given set of numbers. 470 | 471 | 472 | --- 473 | # 6. From 229 Majority Element II [Medium] to 262 Trips and Users [Hard] 474 | > Similarity Distance: 0.6463 475 | 476 | ### >> Reminder: 229 Majority Element II [Medium] 477 | Given an integer array of size n, find all elements that appear more than ⌊n/3⌋ times. 478 | ##### Optimal Python solution: 479 | ```python 480 | class Solution: 481 | def majorityElement(self, nums: List[int]) -> List[int]: 482 | count1, count2, candidate1, candidate2 = 0, 0, 0, 1 483 | for num in nums: 484 | if num == candidate1: 485 | count1 += 1 486 | elif num == candidate2: 487 | count2 += 1 488 | elif count1 == 0: 489 | candidate1, count1 = num, 1 490 | elif count2 == 0: 491 | candidate2, count2 = num, 1 492 | else: 493 | count1, count2 = count1 - 1, count2 - 1 494 | return [n for n in (candidate1, candidate2) if nums.count(n) > len(nums) // 3] 495 | ``` 496 | The essence of this problem is to find the majority elements that appear more than ⌊n/3⌋ times in an array. 497 | 498 | ### >> 262 Trips and Users [Hard] 499 | The Trips table holds all taxi trips. Each trip has a unique Id, while Client_Id and Driver_Id are both foreign keys to the Users_Id at the Users table. Status is an ENUM type of (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’). 500 | ##### Sample input: 501 | Trips table: 502 | +----+-----------+-----------+---------+--------------------+ 503 | | Id | Client_Id | Driver_Id | City_Id | Status | 504 | +----+-----------+-----------+---------+--------------------+ 505 | | 1 | 1 | 10 | 1 | completed | 506 | | 2 | 2 | 11 | 1 | cancelled_by_driver| 507 | | 3 | 3 | 12 | 6 | completed | 508 | | 4 | 4 | 13 | 6 | cancelled_by_client| 509 | +----+-----------+-----------+---------+--------------------+ 510 | Users table: 511 | +------+--------+ 512 | | Id | Banned | 513 | +------+--------+ 514 | | 1 | No | 515 | | 10 | No | 516 | | 11 | Yes | 517 | | 12 | No | 518 | | 13 | Yes | 519 | +------+--------+ 520 | ##### Sample output: 521 | BannedUsers table: 522 | +----------+ 523 | | Id | 524 | +----------+ 525 | | 11 | 526 | | 13 | 527 | +----------+ 528 | 529 | ##### Questions to ask to clarify requirements: 530 | 531 | - What is the expected output format? 532 | - Can there be multiple trips with the same Driver_Id? 533 | - Can there be multiple users with the same Id? 534 | 535 | ##### Optimal Python solution: 536 | ```python 537 | SELECT DISTINCT t.Driver_Id AS Id 538 | FROM Trips t 539 | JOIN Users u ON t.Driver_Id = u.Id 540 | WHERE u.Banned = 'Yes' 541 | ``` 542 | ##### Time complexity: 543 | O(n) 544 | ##### Space complexity: 545 | O(n) 546 | ##### Notes: 547 | 548 | - Use a join operation to combine the Trips and Users tables. 549 | - Use the DISTINCT keyword to remove duplicate entries. 550 | - Filter the result based on the 'Banned' column in the Users table. 551 | 552 | - Understand the syntax and usage of join operations in SQL. 553 | - Use the DISTINCT keyword to remove duplicate entries from the result. 554 | 555 | - Handling duplicate entries in the result. 556 | - Understanding the join operation and its syntax. 557 | 558 | - Using subqueries instead of joins. 559 | - Using the GROUP BY clause instead of DISTINCT. 560 | 561 | ### >> Comparison: 229 Majority Element II [Medium] *VS* 262 Trips and Users [Hard] 562 | > Similarity distance: 0.6463 563 | ##### Similarities 564 | 565 | - Both questions are related to finding elements that appear more than a certain threshold in an array or dataset. 566 | ##### Differences 567 | 568 | - Question 229 focuses on finding the majority elements that appear more than n/3 times in an array, while question 262 focuses on finding the users who have made more than n trips. 569 | - Question 229 requires finding the majority elements in a single array, while question 262 involves analyzing multiple arrays and their relationships. 570 | - Question 229 has a complexity requirement of O(1) space, while question 262 does not have a specific space complexity requirement. 571 | ##### New Insights in 262 Trips and Users [Hard] 572 | 573 | - Question 229 introduces the concept of finding majority elements using the Boyer-Moore Voting Algorithm. 574 | - Question 262 introduces the concept of analyzing user trips and their relationships using SQL queries. 575 | 576 | -------------------------------------------------------------------------------- /intensive_study_guides/20231226_040350/leetcode_intensive_day_000024.md: -------------------------------------------------------------------------------- 1 | 2 | # Leetcode Intensive Tutorial Day 24 3 | > [Difficulty Score: 17] 4 | 5 | > [Version: 20231226_040350] 6 | 7 | > [Including this day, you had studied : 185 leetcode problems] 8 | 9 | 10 | ## Courses overview of the day 11 | 12 | - 234 Palindrome Linked List [Easy] 13 | - 143 Reorder List [Medium] 14 | - 148 Sort List [Medium] 15 | - 272 Closest Binary Search Tree Value II [Hard] 16 | - 99 Recover Binary Search Tree [Hard] 17 | - 24 Swap Nodes in Pairs [Medium] 18 | - 328 Odd Even Linked List [Medium] 19 | 20 | #### Step by step 21 | 22 | - [1. From 234 Palindrome Linked List [Easy] to 143 Reorder List [Medium]](#1-from-234-palindrome-linked-list-easy-to-143-reorder-list-medium)) 23 | 24 | - [2. From 143 Reorder List [Medium] to 148 Sort List [Medium]](#2-from-143-reorder-list-medium-to-148-sort-list-medium)) 25 | 26 | - [3. From 143 Reorder List [Medium] to 272 Closest Binary Search Tree Value II [Hard]](#3-from-143-reorder-list-medium-to-272-closest-binary-search-tree-value-ii-hard)) 27 | 28 | - [4. From 272 Closest Binary Search Tree Value II [Hard] to 99 Recover Binary Search Tree [Hard]](#4-from-272-closest-binary-search-tree-value-ii-hard-to-99-recover-binary-search-tree-hard)) 29 | 30 | - [5. From 143 Reorder List [Medium] to 24 Swap Nodes in Pairs [Medium]](#5-from-143-reorder-list-medium-to-24-swap-nodes-in-pairs-medium)) 31 | 32 | - [6. From 143 Reorder List [Medium] to 328 Odd Even Linked List [Medium]](#6-from-143-reorder-list-medium-to-328-odd-even-linked-list-medium)) 33 | 34 | 35 | 36 | #### Summary 37 | 38 | 39 | - 234 Palindrome Linked List : Check if a linked list is a palindrome by comparing its values with their reverse. 40 | - 24 Swap Nodes in Pairs : Swap every two adjacent nodes in a linked list. 41 | - 99 Recover Binary Search Tree : Recover a binary search tree with two swapped elements without changing its structure. 42 | - 272 Closest Binary Search Tree Value II : Find k values in a binary search tree that are closest to a target value using an inorder traversal and two lists. 43 | - 328 Odd Even Linked List : The essence of the problem is to group all odd nodes together followed by the even nodes in the given linked list in place. 44 | - 143 Reorder List : Reordering a linked list by finding the middle, reversing the second half, and merging the halves 45 | - 148 Sort List : The essence of this problem is to divide the linked list into smaller sublists using merge sort and merge them in sorted order. 46 | > Similarity Diameter of these problems: 0.5603 47 | 48 | 49 | --- 50 | # 1. From 234 Palindrome Linked List [Easy] to 143 Reorder List [Medium] 51 | > Similarity Distance: 0.4497 52 | 53 | ### >> 234 Palindrome Linked List [Easy] 54 | Given a singly linked list, determine if it is a palindrome. 55 | ##### Sample input: 56 | 1->2 57 | 58 | ##### Sample output: 59 | false 60 | 61 | 62 | ##### Questions to ask to clarify requirements: 63 | What is the maximum length of the linked list? Can the linked list be empty? 64 | 65 | ##### Optimal Python solution: 66 | ```python 67 | class Solution: 68 | def isPalindrome(self, head: ListNode) -> bool: 69 | values = [] 70 | current = head 71 | while current: 72 | values.append(current.val) 73 | current = current.next 74 | return values == values[::-1] 75 | 76 | ``` 77 | ##### Time complexity: 78 | O(n) 79 | ##### Space complexity: 80 | O(n) 81 | ##### Notes: 82 | 1. Traverse the linked list and store the values in a list 83 | 2. Check if the list is equal to its reverse 84 | 3. Return True if it is a palindrome, False otherwise 85 | Use the == operator to compare two lists for equality. 86 | The space complexity of the optimal solution is O(n), which can be improved. 87 | Avoid using extra space to store the values of the linked list. 88 | 89 | ### >> 143 Reorder List [Medium] 90 | Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… 91 | ##### Sample input: 92 | 1->2->3->4 93 | ##### Sample output: 94 | 1->4->2->3 95 | 96 | ##### Questions to ask to clarify requirements: 97 | Can we modify the input linked list? What should we do if the length of the linked list is odd? 98 | 99 | ##### Optimal Python solution: 100 | ```python 101 | def reorderList(self, head): 102 | if not head or not head.next: 103 | return 104 | slow = fast = head 105 | while fast and fast.next: 106 | slow = slow.next 107 | fast = fast.next.next 108 | prev, curr = None, slow 109 | while curr: 110 | curr.next, prev, curr = prev, curr, curr.next 111 | first, second = head, prev 112 | while second.next: 113 | first.next, first = second, first.next 114 | second.next, second = first, second.next 115 | ``` 116 | ##### Time complexity: 117 | O(n) 118 | ##### Space complexity: 119 | O(1) 120 | ##### Notes: 121 | 1. Find the middle of the linked list using two pointers 122 | 2. Reverse the second half of the linked list 123 | 3. Merge the first and second halves of the linked list 124 | Use two pointers to find the middle of the linked list 125 | Reversing the second half of the linked list 126 | Using extra space 127 | 128 | ### >> Comparison: 234 Palindrome Linked List [Easy] *VS* 143 Reorder List [Medium] 129 | > Similarity distance: 0.4497 130 | ##### Similarities 131 | 132 | - Both questions involve manipulating a linked list. 133 | - Both questions require rearranging the elements of the linked list. 134 | ##### Differences 135 | 136 | - Question 234 checks if a linked list is a palindrome, while question 143 reorders the elements of the linked list. 137 | - Question 234 requires checking for symmetry in the linked list, while question 143 requires rearranging the elements in a specific order. 138 | - Question 234 has a time complexity of O(n) and space complexity of O(1), while question 143 has a time complexity of O(n) and space complexity of O(1). 139 | ##### New Insights in 143 Reorder List [Medium] 140 | 141 | - Question 234 introduces the concept of checking for palindromes in a linked list. 142 | - Question 143 introduces the concept of reordering elements in a linked list. 143 | 144 | 145 | --- 146 | # 2. From 143 Reorder List [Medium] to 148 Sort List [Medium] 147 | > Similarity Distance: 0.3534 148 | 149 | ### >> Reminder: 143 Reorder List [Medium] 150 | Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… 151 | ##### Optimal Python solution: 152 | ```python 153 | def reorderList(self, head): 154 | if not head or not head.next: 155 | return 156 | slow = fast = head 157 | while fast and fast.next: 158 | slow = slow.next 159 | fast = fast.next.next 160 | prev, curr = None, slow 161 | while curr: 162 | curr.next, prev, curr = prev, curr, curr.next 163 | first, second = head, prev 164 | while second.next: 165 | first.next, first = second, first.next 166 | second.next, second = first, second.next 167 | ``` 168 | Reordering a linked list by finding the middle, reversing the second half, and merging the halves 169 | 170 | ### >> 148 Sort List [Medium] 171 | Sort a linked list in O(n log n) time using constant space complexity. 172 | ##### Sample input: 173 | 4->2->1->3 174 | ##### Sample output: 175 | 1->2->3->4 176 | 177 | ##### Questions to ask to clarify requirements: 178 | What is the maximum length of the linked list? Can the linked list contain duplicates? 179 | 180 | ##### Optimal Python solution: 181 | ```python 182 | def sortList(self, head: ListNode) -> ListNode: 183 | if not head or not head.next: 184 | return head 185 | slow = head 186 | fast = head.next 187 | while fast and fast.next: 188 | slow = slow.next 189 | fast = fast.next.next 190 | mid = slow.next 191 | slow.next = None 192 | left = self.sortList(head) 193 | right = self.sortList(mid) 194 | return self.merge(left, right) 195 | 196 | 197 | def merge(self, l1: ListNode, l2: ListNode) -> ListNode: 198 | dummy = ListNode(0) 199 | curr = dummy 200 | while l1 and l2: 201 | if l1.val < l2.val: 202 | curr.next = l1 203 | l1 = l1.next 204 | else: 205 | curr.next = l2 206 | l2 = l2.next 207 | curr = curr.next 208 | if l1: 209 | curr.next = l1 210 | if l2: 211 | curr.next = l2 212 | return dummy.next 213 | ``` 214 | ##### Time complexity: 215 | O(n log n) 216 | ##### Space complexity: 217 | O(1) 218 | ##### Notes: 219 | 1. Use merge sort to divide the linked list into smaller sublists. 220 | 2. Merge the sublists in sorted order. 221 | 3. Time complexity: O(n log n). 222 | 4. Space complexity: O(1). 223 | Implement the merge sort algorithm with linked lists. 224 | The main challenge is to correctly divide the linked list into smaller sublists and merge them in sorted order. 225 | Avoid using sorting algorithms with higher time complexity or additional data structures. 226 | 227 | ### >> Comparison: 143 Reorder List [Medium] *VS* 148 Sort List [Medium] 228 | > Similarity distance: 0.3534 229 | ##### Similarities 230 | 231 | - Both questions involve manipulating a linked list. 232 | - Both questions have a time complexity of O(n log n). 233 | ##### Differences 234 | 235 | - 143 Reorder List involves reordering the list in a specific way, while 148 Sort List involves sorting the list in ascending order. 236 | - 143 Reorder List requires rearranging the nodes in the list, while 148 Sort List requires rearranging the values within the nodes. 237 | - 143 Reorder List has a space complexity of O(1), while 148 Sort List has a space complexity of O(log n). 238 | ##### New Insights in 148 Sort List [Medium] 239 | 240 | - In 143 Reorder List, we can split the list into two halves, reverse the second half, and then merge the two halves alternately to achieve the desired reordering. 241 | - In 148 Sort List, we can use the merge sort algorithm to sort the list in O(n log n) time complexity. 242 | 243 | 244 | --- 245 | # 3. From 143 Reorder List [Medium] to 272 Closest Binary Search Tree Value II [Hard] 246 | > Similarity Distance: 0.4029 247 | 248 | ### >> Reminder: 143 Reorder List [Medium] 249 | Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… 250 | ##### Optimal Python solution: 251 | ```python 252 | def reorderList(self, head): 253 | if not head or not head.next: 254 | return 255 | slow = fast = head 256 | while fast and fast.next: 257 | slow = slow.next 258 | fast = fast.next.next 259 | prev, curr = None, slow 260 | while curr: 261 | curr.next, prev, curr = prev, curr, curr.next 262 | first, second = head, prev 263 | while second.next: 264 | first.next, first = second, first.next 265 | second.next, second = first, second.next 266 | ``` 267 | Reordering a linked list by finding the middle, reversing the second half, and merging the halves 268 | 269 | ### >> 272 Closest Binary Search Tree Value II [Hard] 270 | Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target. 271 | ##### Sample input: 272 | 273 | - root = [4,2,5,1,3], target = 3.714286, k = 2 274 | ##### Sample output: 275 | 276 | - [3,4] 277 | 278 | ##### Questions to ask to clarify requirements: 279 | 280 | - What should be returned if there are less than k values in the BST? 281 | - Can the target value be outside the range of values in the BST? 282 | - What is the expected time complexity of the solution? 283 | 284 | ##### Optimal Python solution: 285 | ```python 286 | 287 | - class Solution: 288 | - def closestKValues(self, root: TreeNode, target: float, k: int) -> List[int]: 289 | - stack, pred, succ = [], [], [] 290 | - while stack or root: 291 | - while root: 292 | - stack.append(root) 293 | - root = root.left 294 | - root = stack.pop() 295 | - if root.val <= target: 296 | - pred.append(root.val) 297 | - if len(pred) > k: 298 | - pred.pop(0) 299 | - else: 300 | - succ.append(root.val) 301 | - if len(succ) > k: 302 | - succ.pop(0) 303 | - else: 304 | - break 305 | - root = root.right 306 | - return pred if target - pred[0] < succ[-1] - target else succ 307 | ``` 308 | ##### Time complexity: 309 | O(n) 310 | ##### Space complexity: 311 | O(k) 312 | ##### Notes: 313 | 314 | - Use a stack to traverse the BST in inorder 315 | - Maintain two lists: one for values less than or equal to the target, and one for values greater than the target 316 | - Keep track of the k closest values by removing the first element if the list size exceeds k 317 | 318 | - Use a stack to traverse the BST in inorder 319 | - Use two lists to store values less than or equal to the target and values greater than the target 320 | 321 | - Handling an empty BST 322 | - Finding the k closest values 323 | 324 | - Using a brute force approach to find all values in the BST 325 | - Using a large amount of additional memory 326 | 327 | ### >> Comparison: 143 Reorder List [Medium] *VS* 272 Closest Binary Search Tree Value II [Hard] 328 | > Similarity distance: 0.4029 329 | ##### Similarities 330 | 331 | - Both questions involve manipulating a linked list or a binary search tree. 332 | - Both questions require rearranging or reordering the elements in the data structure. 333 | - Both questions have a time complexity of O(n). 334 | ##### Differences 335 | 336 | - Question 143 involves reordering a linked list by modifying the pointers, while question 272 involves finding the closest values in a binary search tree. 337 | - Question 143 requires rearranging the elements in-place, while question 272 requires finding the values and returning them in a specific order. 338 | - Question 143 has a space complexity of O(1), while question 272 has a space complexity of O(k), where k is the number of closest values to be returned. 339 | ##### New Insights in 272 Closest Binary Search Tree Value II [Hard] 340 | 341 | - Question 143 teaches us how to manipulate pointers in a linked list to reorder the elements efficiently. 342 | - Question 272 teaches us how to traverse a binary search tree and find the closest values to a given target. 343 | 344 | 345 | --- 346 | # 4. From 272 Closest Binary Search Tree Value II [Hard] to 99 Recover Binary Search Tree [Hard] 347 | > Similarity Distance: 0.4415 348 | 349 | ### >> Reminder: 272 Closest Binary Search Tree Value II [Hard] 350 | Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target. 351 | ##### Optimal Python solution: 352 | ```python 353 | 354 | - class Solution: 355 | - def closestKValues(self, root: TreeNode, target: float, k: int) -> List[int]: 356 | - stack, pred, succ = [], [], [] 357 | - while stack or root: 358 | - while root: 359 | - stack.append(root) 360 | - root = root.left 361 | - root = stack.pop() 362 | - if root.val <= target: 363 | - pred.append(root.val) 364 | - if len(pred) > k: 365 | - pred.pop(0) 366 | - else: 367 | - succ.append(root.val) 368 | - if len(succ) > k: 369 | - succ.pop(0) 370 | - else: 371 | - break 372 | - root = root.right 373 | - return pred if target - pred[0] < succ[-1] - target else succ 374 | ``` 375 | Find k values in a binary search tree that are closest to a target value using an inorder traversal and two lists. 376 | 377 | ### >> 99 Recover Binary Search Tree [Hard] 378 | Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. 379 | ##### Sample input: 380 | 381 | - [1,3,null,null,2] 382 | ##### Sample output: 383 | 384 | - [3,1,null,null,2] 385 | 386 | ##### Questions to ask to clarify requirements: 387 | 388 | - Can we assume that there are only two elements swapped? 389 | - Can we modify the structure of the tree? 390 | - Can we use extra space? 391 | 392 | ##### Optimal Python solution: 393 | ```python 394 | 395 | - class Solution: 396 | - def recoverTree(self, root: TreeNode) -> None: 397 | - def inorder(node): 398 | - if not node: 399 | - return 400 | - inorder(node.left) 401 | - if self.prev and self.prev.val > node.val: 402 | - if not self.first: 403 | - self.first = self.prev 404 | - self.second = node 405 | - self.prev = node 406 | - inorder(node.right) 407 | - self.prev = self.first = self.second = None 408 | - inorder(root) 409 | - self.first.val, self.second.val = self.second.val, self.first.val 410 | ``` 411 | ##### Time complexity: 412 | O(n) 413 | ##### Space complexity: 414 | O(1) 415 | ##### Notes: 416 | 417 | - Use inorder traversal to find the swapped elements 418 | - Swap the values of the two elements 419 | - Do not change the structure of the tree 420 | 421 | - Use a recursive function for inorder traversal 422 | - Keep track of the previous node visited 423 | - Swap the values of the two elements 424 | 425 | - Identifying the swapped elements during inorder traversal 426 | 427 | - Modifying the structure of the tree 428 | - Using extra space 429 | 430 | ### >> Comparison: 272 Closest Binary Search Tree Value II [Hard] *VS* 99 Recover Binary Search Tree [Hard] 431 | > Similarity distance: 0.4415 432 | ##### Similarities 433 | 434 | - Both questions are related to binary search trees (BST). 435 | - Both questions are classified as hard difficulty. 436 | ##### Differences 437 | 438 | - 272 Closest Binary Search Tree Value II focuses on finding the k closest values to a target value in a BST. 439 | - 99 Recover Binary Search Tree focuses on recovering a BST that has two nodes swapped. 440 | ##### New Insights in 99 Recover Binary Search Tree [Hard] 441 | 442 | - From 272 Closest Binary Search Tree Value II, we can learn how to perform an inorder traversal of a BST and maintain a list of k closest values. 443 | - From 99 Recover Binary Search Tree, we can learn how to identify and swap two incorrectly placed nodes in a BST. 444 | 445 | 446 | --- 447 | # 5. From 143 Reorder List [Medium] to 24 Swap Nodes in Pairs [Medium] 448 | > Similarity Distance: 0.4088 449 | 450 | ### >> Reminder: 143 Reorder List [Medium] 451 | Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… 452 | ##### Optimal Python solution: 453 | ```python 454 | def reorderList(self, head): 455 | if not head or not head.next: 456 | return 457 | slow = fast = head 458 | while fast and fast.next: 459 | slow = slow.next 460 | fast = fast.next.next 461 | prev, curr = None, slow 462 | while curr: 463 | curr.next, prev, curr = prev, curr, curr.next 464 | first, second = head, prev 465 | while second.next: 466 | first.next, first = second, first.next 467 | second.next, second = first, second.next 468 | ``` 469 | Reordering a linked list by finding the middle, reversing the second half, and merging the halves 470 | 471 | ### >> 24 Swap Nodes in Pairs [Medium] 472 | Given a linked list, swap every two adjacent nodes and return its head. 473 | ##### Sample input: 474 | [1,2,3,4] 475 | ##### Sample output: 476 | [2,1,4,3] 477 | 478 | ##### Questions to ask to clarify requirements: 479 | 480 | - Can the input list be empty? 481 | - Can the input list contain cycles? 482 | - What is the maximum length of the input list? 483 | 484 | ##### Optimal Python solution: 485 | ```python 486 | def swapPairs(self, head: ListNode) -> ListNode: 487 | dummy = ListNode() 488 | dummy.next = head 489 | prev = dummy 490 | while head and head.next: 491 | first = head 492 | second = head.next 493 | prev.next = second 494 | first.next = second.next 495 | second.next = first 496 | prev = first 497 | head = first.next 498 | return dummy.next 499 | ``` 500 | ##### Time complexity: 501 | O(N) 502 | ##### Space complexity: 503 | O(1) 504 | ##### Notes: 505 | 506 | - Use a dummy node to simplify the swapping process 507 | - Iterate through the list and swap every two adjacent nodes 508 | 509 | - Use a dummy node to simplify the swapping process. 510 | - Iterate through the list and swap every two adjacent nodes. 511 | - Update the previous node after each swap. 512 | 513 | - Handling empty list as input 514 | - Updating the previous node after swapping nodes 515 | 516 | - Using recursion to swap nodes 517 | - Using a quadratic time complexity solution 518 | 519 | ### >> Comparison: 143 Reorder List [Medium] *VS* 24 Swap Nodes in Pairs [Medium] 520 | > Similarity distance: 0.4088 521 | ##### Similarities 522 | 523 | - Both questions are classified as medium difficulty. 524 | - Both questions involve manipulating linked lists. 525 | - Both questions require reordering or swapping elements in the linked list. 526 | ##### Differences 527 | 528 | - In 'Reorder List', the linked list needs to be reordered in a specific way. 529 | - In 'Swap Nodes in Pairs', adjacent nodes need to be swapped in pairs. 530 | - The implementation details for reordering and swapping are different in each question. 531 | ##### New Insights in 24 Swap Nodes in Pairs [Medium] 532 | 533 | - In 'Reorder List', we can use a combination of reversing and merging techniques to reorder the linked list. 534 | - In 'Swap Nodes in Pairs', we can use a recursive approach to swap the nodes in pairs. 535 | 536 | 537 | --- 538 | # 6. From 143 Reorder List [Medium] to 328 Odd Even Linked List [Medium] 539 | > Similarity Distance: 0.4679 540 | 541 | ### >> Reminder: 143 Reorder List [Medium] 542 | Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… 543 | ##### Optimal Python solution: 544 | ```python 545 | def reorderList(self, head): 546 | if not head or not head.next: 547 | return 548 | slow = fast = head 549 | while fast and fast.next: 550 | slow = slow.next 551 | fast = fast.next.next 552 | prev, curr = None, slow 553 | while curr: 554 | curr.next, prev, curr = prev, curr, curr.next 555 | first, second = head, prev 556 | while second.next: 557 | first.next, first = second, first.next 558 | second.next, second = first, second.next 559 | ``` 560 | Reordering a linked list by finding the middle, reversing the second half, and merging the halves 561 | 562 | ### >> 328 Odd Even Linked List [Medium] 563 | Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes. 564 | You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity. 565 | ##### Sample input: 566 | 1->2->3->4->5 567 | ##### Sample output: 568 | 1->3->5->2->4 569 | 570 | ##### Questions to ask to clarify requirements: 571 | Can the linked list be empty? Can the linked list contain duplicate values? 572 | 573 | ##### Optimal Python solution: 574 | ```python 575 | class Solution: 576 | def oddEvenList(self, head: ListNode) -> ListNode: 577 | if not head or not head.next: 578 | return head 579 | odd = head 580 | even = head.next 581 | even_head = even 582 | while even and even.next: 583 | odd.next = even.next 584 | odd = odd.next 585 | even.next = odd.next 586 | even = even.next 587 | odd.next = even_head 588 | return head 589 | ``` 590 | ##### Time complexity: 591 | O(n) 592 | ##### Space complexity: 593 | O(1) 594 | ##### Notes: 595 | 1. Use two pointers to track the odd and even nodes. 596 | 2. Use a separate variable to track the head of the even nodes. 597 | 3. Update the next pointers of the odd and even nodes. 598 | 1. Use two pointers to track the odd and even nodes. 599 | 2. Use a separate variable to track the head of the even nodes. 600 | 3. Update the next pointers of the odd and even nodes. 601 | The solution should be done in place and should have O(1) space complexity. 602 | Avoid using extra space to store the odd and even nodes separately. 603 | 604 | ### >> Comparison: 143 Reorder List [Medium] *VS* 328 Odd Even Linked List [Medium] 605 | > Similarity distance: 0.4679 606 | ##### Similarities 607 | 608 | - Both questions involve manipulating a linked list. 609 | - Both questions require rearranging the elements of the linked list. 610 | ##### Differences 611 | 612 | - 143 Reorder List reorders the list in a specific pattern, while 328 Odd Even Linked List separates odd and even nodes. 613 | - 143 Reorder List modifies the original list, while 328 Odd Even Linked List creates a new list. 614 | - 143 Reorder List has a time complexity of O(n), while 328 Odd Even Linked List has a time complexity of O(n/2). 615 | ##### New Insights in 328 Odd Even Linked List [Medium] 616 | 617 | - In 143 Reorder List, we can use a two-pointer approach to find the middle of the list. 618 | - In 328 Odd Even Linked List, we can use two separate pointers to keep track of odd and even nodes. 619 | 620 | -------------------------------------------------------------------------------- /intensive_study_guides/20231226_040350/leetcode_intensive_day_000039.md: -------------------------------------------------------------------------------- 1 | 2 | # Leetcode Intensive Tutorial Day 39 3 | > [Difficulty Score: 20] 4 | 5 | > [Version: 20231226_040350] 6 | 7 | > [Including this day, you had studied : 323 leetcode problems] 8 | 9 | 10 | ## Courses overview of the day 11 | 12 | - 16 3Sum Closest [Medium] 13 | - 15 3Sum [Medium] 14 | - 259 3Sum Smaller [Medium] 15 | - 4 Median of Two Sorted Arrays [Hard] 16 | - 462 Minimum Moves to Equal Array Elements II [Medium] 17 | - 480 Sliding Window Median [Hard] 18 | - 571 Find Median Given Frequency of Numbers [Hard] 19 | 20 | #### Step by step 21 | 22 | - [1. From 16 3Sum Closest [Medium] to 15 3Sum [Medium]](#1-from-16-3sum-closest-medium-to-15-3sum-medium)) 23 | 24 | - [2. From 15 3Sum [Medium] to 259 3Sum Smaller [Medium]](#2-from-15-3sum-medium-to-259-3sum-smaller-medium)) 25 | 26 | - [3. From 16 3Sum Closest [Medium] to 4 Median of Two Sorted Arrays [Hard]](#3-from-16-3sum-closest-medium-to-4-median-of-two-sorted-arrays-hard)) 27 | 28 | - [4. From 4 Median of Two Sorted Arrays [Hard] to 462 Minimum Moves to Equal Array Elements II [Medium]](#4-from-4-median-of-two-sorted-arrays-hard-to-462-minimum-moves-to-equal-array-elements-ii-medium)) 29 | 30 | - [5. From 462 Minimum Moves to Equal Array Elements II [Medium] to 480 Sliding Window Median [Hard]](#5-from-462-minimum-moves-to-equal-array-elements-ii-medium-to-480-sliding-window-median-hard)) 31 | 32 | - [6. From 4 Median of Two Sorted Arrays [Hard] to 571 Find Median Given Frequency of Numbers [Hard]](#6-from-4-median-of-two-sorted-arrays-hard-to-571-find-median-given-frequency-of-numbers-hard)) 33 | 34 | 35 | 36 | #### Summary 37 | 38 | 39 | - 571 Find Median Given Frequency of Numbers : Given a list of numbers and their frequencies, find the median of the numbers. 40 | - 480 Sliding Window Median : The essence of this problem is to find the median of each window in a given array using a sliding window approach. 41 | - 16 3Sum Closest : Finding three integers in an array that have the closest sum to a target. 42 | - 259 3Sum Smaller : Given an array and a target, find the number of triplets with sum less than the target. 43 | - 4 Median of Two Sorted Arrays : The essence of this problem is to merge and sort two sorted arrays to find the median. 44 | - 462 Minimum Moves to Equal Array Elements II : The minimum number of moves required to make all array elements equal is the sum of absolute differences between each element and the median. 45 | - 15 3Sum : Finding unique triplets that sum up to zero in an array. 46 | > Similarity Diameter of these problems: 0.6861 47 | 48 | 49 | --- 50 | # 1. From 16 3Sum Closest [Medium] to 15 3Sum [Medium] 51 | > Similarity Distance: 0.2184 52 | 53 | ### >> 16 3Sum Closest [Medium] 54 | Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. 55 | ##### Sample input: 56 | [-1,2,1,-4], 1 57 | ##### Sample output: 58 | 2 59 | 60 | ##### Questions to ask to clarify requirements: 61 | 62 | - Can the input array contain duplicate triplets? 63 | - Can the input array contain negative numbers? 64 | 65 | ##### Optimal Python solution: 66 | ```python 67 | def threeSumClosest(nums, target): 68 | nums.sort() 69 | closest_sum = float('inf') 70 | for i in range(len(nums)-2): 71 | l, r = i+1, len(nums)-1 72 | while l < r: 73 | curr_sum = nums[i] + nums[l] + nums[r] 74 | if curr_sum == target: 75 | return curr_sum 76 | if abs(curr_sum - target) < abs(closest_sum - target): 77 | closest_sum = curr_sum 78 | if curr_sum < target: 79 | l += 1 80 | else: 81 | r -= 1 82 | return closest_sum 83 | ``` 84 | ##### Time complexity: 85 | O(n^2) 86 | ##### Space complexity: 87 | O(1) 88 | ##### Notes: 89 | 90 | - Sort the array 91 | - Use two pointers to find the closest sum 92 | 93 | - Remember to handle duplicate triplets by skipping duplicate elements during the iteration. 94 | 95 | - Handling duplicate triplets 96 | 97 | - Using a brute force approach 98 | 99 | ### >> 15 3Sum [Medium] 100 | Given an array nums of n integers, find all unique triplets in the array which gives the sum of zero. 101 | ##### Sample input: 102 | [-1,0,1,2,-1,-4] 103 | ##### Sample output: 104 | [[-1,-1,2],[-1,0,1]] 105 | 106 | ##### Questions to ask to clarify requirements: 107 | 108 | - Can the input array contain duplicate triplets? 109 | - Can the input array contain negative numbers? 110 | 111 | ##### Optimal Python solution: 112 | ```python 113 | def threeSum(nums): 114 | nums.sort() 115 | res = [] 116 | for i in range(len(nums)-2): 117 | if i > 0 and nums[i] == nums[i-1]: 118 | continue 119 | l, r = i+1, len(nums)-1 120 | while l < r: 121 | s = nums[i] + nums[l] + nums[r] 122 | if s < 0: 123 | l += 1 124 | elif s > 0: 125 | r -= 1 126 | else: 127 | res.append([nums[i], nums[l], nums[r]]) 128 | while l < r and nums[l] == nums[l+1]: 129 | l += 1 130 | while l < r and nums[r] == nums[r-1]: 131 | r -= 1 132 | l += 1 133 | r -= 1 134 | return res 135 | ``` 136 | ##### Time complexity: 137 | O(n^2) 138 | ##### Space complexity: 139 | O(1) 140 | ##### Notes: 141 | 142 | - Sort the array 143 | - Use two pointers to find the triplets 144 | 145 | - Remember to handle duplicate triplets by skipping duplicate elements during the iteration. 146 | 147 | - Handling duplicate triplets 148 | 149 | - Using a brute force approach 150 | 151 | ### >> Comparison: 16 3Sum Closest [Medium] *VS* 15 3Sum [Medium] 152 | > Similarity distance: 0.2184 153 | ##### Similarities 154 | 155 | - Both questions are related to finding three numbers in an array that sum up to a target value. 156 | - Both questions have a similar input format, where an array of integers is given as input. 157 | ##### Differences 158 | 159 | - The 3Sum Closest question requires finding the sum of three numbers that is closest to a target value, while the 3Sum question requires finding the unique triplets that sum up to zero. 160 | - The 3Sum Closest question has a single target value, while the 3Sum question has a target value of zero. 161 | - The 3Sum Closest question has a return type of integer, representing the sum of the three numbers, while the 3Sum question has a return type of array of arrays, representing the unique triplets. 162 | ##### New Insights in 15 3Sum [Medium] 163 | 164 | - Both questions require using a two-pointer approach to efficiently find the desired triplets or sum. 165 | - Both questions can benefit from sorting the input array to optimize the solution. 166 | - Both questions involve handling duplicate elements in the input array to avoid duplicate triplets or sums. 167 | 168 | 169 | --- 170 | # 2. From 15 3Sum [Medium] to 259 3Sum Smaller [Medium] 171 | > Similarity Distance: 0.2721 172 | 173 | ### >> Reminder: 15 3Sum [Medium] 174 | Given an array nums of n integers, find all unique triplets in the array which gives the sum of zero. 175 | ##### Optimal Python solution: 176 | ```python 177 | def threeSum(nums): 178 | nums.sort() 179 | res = [] 180 | for i in range(len(nums)-2): 181 | if i > 0 and nums[i] == nums[i-1]: 182 | continue 183 | l, r = i+1, len(nums)-1 184 | while l < r: 185 | s = nums[i] + nums[l] + nums[r] 186 | if s < 0: 187 | l += 1 188 | elif s > 0: 189 | r -= 1 190 | else: 191 | res.append([nums[i], nums[l], nums[r]]) 192 | while l < r and nums[l] == nums[l+1]: 193 | l += 1 194 | while l < r and nums[r] == nums[r-1]: 195 | r -= 1 196 | l += 1 197 | r -= 1 198 | return res 199 | ``` 200 | Finding unique triplets that sum up to zero in an array. 201 | 202 | ### >> 259 3Sum Smaller [Medium] 203 | Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 <= i < j < k < n that satisfy the condition nums[i] + nums[j] + nums[k] < target. 204 | ##### Sample input: 205 | nums = [-2,0,1,3], target = 2 206 | ##### Sample output: 207 | 2 208 | 209 | ##### Questions to ask to clarify requirements: 210 | Are there any constraints on the size of the array? Can the array contain duplicate elements? 211 | 212 | ##### Optimal Python solution: 213 | ```python 214 | def threeSumSmaller(nums, target): 215 | nums.sort() 216 | count = 0 217 | for i in range(len(nums)-2): 218 | left = i + 1 219 | right = len(nums) - 1 220 | while left < right: 221 | if nums[i] + nums[left] + nums[right] < target: 222 | count += right - left 223 | left += 1 224 | else: 225 | right -= 1 226 | return count 227 | ``` 228 | ##### Time complexity: 229 | O(n^2) 230 | ##### Space complexity: 231 | O(1) 232 | ##### Notes: 233 | 234 | - Sort the array in ascending order 235 | - Use two pointers to find the triplets that satisfy the condition 236 | - Count the number of valid triplets 237 | 238 | - Handle duplicate elements in the array 239 | 240 | - Handling duplicate triplets 241 | 242 | - Using a brute force approach with three nested loops 243 | 244 | ### >> Comparison: 15 3Sum [Medium] *VS* 259 3Sum Smaller [Medium] 245 | > Similarity distance: 0.2721 246 | ##### Similarities 247 | 248 | - Both questions are related to finding triplets in an array that sum up to a target value. 249 | - Both questions have a time complexity of O(n^2). 250 | ##### Differences 251 | 252 | - Question 15 (3Sum) requires finding unique triplets that sum up to zero, while question 259 (3Sum Smaller) requires finding the number of triplets that sum up to a target value. 253 | - Question 15 (3Sum) allows duplicate numbers in the array, while question 259 (3Sum Smaller) does not. 254 | - Question 15 (3Sum) returns the unique triplets, while question 259 (3Sum Smaller) returns the count of valid triplets. 255 | ##### New Insights in 259 3Sum Smaller [Medium] 256 | 257 | - Question 15 (3Sum) can be solved using a two-pointer approach, where the array is sorted and two pointers are used to find the triplets. 258 | - Question 259 (3Sum Smaller) can be solved using a two-pointer approach as well, but with a slight modification to count the valid triplets. 259 | 260 | 261 | --- 262 | # 3. From 16 3Sum Closest [Medium] to 4 Median of Two Sorted Arrays [Hard] 263 | > Similarity Distance: 0.5388 264 | 265 | ### >> Reminder: 16 3Sum Closest [Medium] 266 | Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. 267 | ##### Optimal Python solution: 268 | ```python 269 | def threeSumClosest(nums, target): 270 | nums.sort() 271 | closest_sum = float('inf') 272 | for i in range(len(nums)-2): 273 | l, r = i+1, len(nums)-1 274 | while l < r: 275 | curr_sum = nums[i] + nums[l] + nums[r] 276 | if curr_sum == target: 277 | return curr_sum 278 | if abs(curr_sum - target) < abs(closest_sum - target): 279 | closest_sum = curr_sum 280 | if curr_sum < target: 281 | l += 1 282 | else: 283 | r -= 1 284 | return closest_sum 285 | ``` 286 | Finding three integers in an array that have the closest sum to a target. 287 | 288 | ### >> 4 Median of Two Sorted Arrays [Hard] 289 | Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. 290 | ##### Sample input: 291 | nums1 = [1,3], nums2 = [2] 292 | ##### Sample output: 293 | 2.00000 294 | 295 | ##### Questions to ask to clarify requirements: 296 | What should be the output if both arrays are empty? 297 | 298 | ##### Optimal Python solution: 299 | ```python 300 | class Solution: 301 | def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: 302 | merged = sorted(nums1 + nums2) 303 | n = len(merged) 304 | if n % 2 == 0: 305 | return (merged[n // 2 - 1] + merged[n // 2]) / 2 306 | else: 307 | return merged[n // 2] 308 | ``` 309 | ##### Time complexity: 310 | O((m + n) log(m + n)) 311 | ##### Space complexity: 312 | O(m + n) 313 | ##### Notes: 314 | Merge the two sorted arrays and find the median. If the total number of elements is odd, return the middle element. If the total number of elements is even, return the average of the two middle elements. 315 | Use the sorted() function to merge and sort the arrays. Handle the case when both arrays are empty separately. 316 | Handling the case when both arrays are empty. 317 | Using brute force approach to merge and sort the arrays. 318 | 319 | ### >> Comparison: 16 3Sum Closest [Medium] *VS* 4 Median of Two Sorted Arrays [Hard] 320 | > Similarity distance: 0.5388 321 | ##### Similarities 322 | 323 | - Both questions involve finding the closest sum or median of elements in arrays. 324 | - Both questions require sorting the input arrays. 325 | - Both questions have a time complexity of O(n^2) or O(log(m+n)). 326 | ##### Differences 327 | 328 | - 3Sum Closest involves finding the closest sum of three elements, while Median of Two Sorted Arrays involves finding the median of two arrays. 329 | - 3Sum Closest uses a two-pointer approach, while Median of Two Sorted Arrays uses a binary search approach. 330 | - 3Sum Closest has a time complexity of O(n^2), while Median of Two Sorted Arrays has a time complexity of O(log(m+n)). 331 | ##### New Insights in 4 Median of Two Sorted Arrays [Hard] 332 | 333 | - From 3Sum Closest, we can learn how to efficiently find the closest sum of three elements in an array. 334 | - From Median of Two Sorted Arrays, we can learn how to find the median of two sorted arrays in an efficient manner. 335 | 336 | 337 | --- 338 | # 4. From 4 Median of Two Sorted Arrays [Hard] to 462 Minimum Moves to Equal Array Elements II [Medium] 339 | > Similarity Distance: 0.4688 340 | 341 | ### >> Reminder: 4 Median of Two Sorted Arrays [Hard] 342 | Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. 343 | ##### Optimal Python solution: 344 | ```python 345 | class Solution: 346 | def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: 347 | merged = sorted(nums1 + nums2) 348 | n = len(merged) 349 | if n % 2 == 0: 350 | return (merged[n // 2 - 1] + merged[n // 2]) / 2 351 | else: 352 | return merged[n // 2] 353 | ``` 354 | The essence of this problem is to merge and sort two sorted arrays to find the median. 355 | 356 | ### >> 462 Minimum Moves to Equal Array Elements II [Medium] 357 | Given an integer array nums of size n, return the minimum number of moves required to make all array elements equal. In one move, you can increment or decrement an element of the array by 1. 358 | ##### Sample input: 359 | [1,2,3] 360 | ##### Sample output: 361 | 2 362 | 363 | ##### Questions to ask to clarify requirements: 364 | None 365 | 366 | ##### Optimal Python solution: 367 | ```python 368 | def minMoves2(nums: List[int]) -> int: 369 | nums.sort() 370 | median = nums[len(nums) // 2] 371 | return sum(abs(num - median) for num in nums) 372 | ``` 373 | ##### Time complexity: 374 | O(nlogn) 375 | ##### Space complexity: 376 | O(1) 377 | ##### Notes: 378 | Find the median of the array and calculate the sum of absolute differences between each element and the median. 379 | None 380 | None 381 | None 382 | 383 | ### >> Comparison: 4 Median of Two Sorted Arrays [Hard] *VS* 462 Minimum Moves to Equal Array Elements II [Medium] 384 | > Similarity distance: 0.4688 385 | ##### Similarities 386 | 387 | - Both questions involve manipulating arrays. 388 | - Both questions require finding a specific value or range of values in the arrays. 389 | - Both questions have a complexity of O(log(min(m, n))) in terms of time complexity. 390 | ##### Differences 391 | 392 | - Median of Two Sorted Arrays involves finding the median value of the combined sorted arrays. 393 | - Minimum Moves to Equal Array Elements II involves finding the minimum number of moves required to make all elements in the array equal. 394 | - Median of Two Sorted Arrays is classified as a Hard level question, while Minimum Moves to Equal Array Elements II is classified as a Medium level question. 395 | - Median of Two Sorted Arrays requires a more complex algorithm, such as the binary search approach, to solve the problem efficiently. 396 | - Minimum Moves to Equal Array Elements II can be solved using the median value of the array. 397 | ##### New Insights in 462 Minimum Moves to Equal Array Elements II [Medium] 398 | 399 | - Median of Two Sorted Arrays teaches us how to efficiently find the median value of two sorted arrays. 400 | - Minimum Moves to Equal Array Elements II teaches us how to find the minimum number of moves required to make all elements in an array equal, using the median value as a pivot. 401 | 402 | 403 | --- 404 | # 5. From 462 Minimum Moves to Equal Array Elements II [Medium] to 480 Sliding Window Median [Hard] 405 | > Similarity Distance: 0.4941 406 | 407 | ### >> Reminder: 462 Minimum Moves to Equal Array Elements II [Medium] 408 | Given an integer array nums of size n, return the minimum number of moves required to make all array elements equal. In one move, you can increment or decrement an element of the array by 1. 409 | ##### Optimal Python solution: 410 | ```python 411 | def minMoves2(nums: List[int]) -> int: 412 | nums.sort() 413 | median = nums[len(nums) // 2] 414 | return sum(abs(num - median) for num in nums) 415 | ``` 416 | The minimum number of moves required to make all array elements equal is the sum of absolute differences between each element and the median. 417 | 418 | ### >> 480 Sliding Window Median [Hard] 419 | Find the median of each window in a given array. 420 | ##### Sample input: 421 | [1,3,-1,-3,5,3,6,7] 422 | 3 423 | 424 | Output: 425 | [1,-1,-1,3,5,6] 426 | ##### Sample output: 427 | [1,-1,-1,3,5,6] 428 | 429 | ##### Questions to ask to clarify requirements: 430 | What should be the output format? Can the input array contain duplicates? 431 | 432 | ##### Optimal Python solution: 433 | ```python 434 | import bisect 435 | 436 | class Solution: 437 | def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]: 438 | window = sorted(nums[:k]) 439 | medians = [] 440 | for i in range(k, len(nums) + 1): 441 | medians.append((window[k // 2] + window[(k - 1) // 2]) / 2) 442 | if i == len(nums): 443 | break 444 | window.remove(nums[i - k]) 445 | bisect.insort(window, nums[i]) 446 | return medians 447 | ``` 448 | ##### Time complexity: 449 | O(n * k * log(k)) 450 | ##### Space complexity: 451 | O(k) 452 | ##### Notes: 453 | 1. Use a sliding window to iterate through the array. 454 | 2. Maintain a sorted window to efficiently find the median. 455 | 3. Calculate the median by taking the average of the middle two elements if the window size is even. 456 | 4. Remove the first element of the window and insert the next element in the sorted window for each iteration. 457 | 5. Return the list of medians. 458 | 1. Use the bisect module to efficiently maintain a sorted window. 459 | 2. Use the remove() and insort() methods to remove and insert elements in a sorted list. 460 | 3. Use the index() method to find the position of an element in a list. 461 | 4. Use if statements to handle edge cases. 462 | 1. Maintaining a sorted window efficiently by using the bisect module. 463 | 2. Calculating the median by taking the average of the middle two elements if the window size is even. 464 | 3. Removing the first element of the window and inserting the next element in the sorted window. 465 | 4. Handling edge cases where the window size is larger than the array size. 466 | 1. Sorting the window for each iteration. 467 | 2. Calculating the median by finding the middle element(s) of the window. 468 | 3. Removing and inserting elements in the window by using the index() and insert() methods. 469 | 4. Handling edge cases where the window size is larger than the array size by using if statements. 470 | 471 | ### >> Comparison: 462 Minimum Moves to Equal Array Elements II [Medium] *VS* 480 Sliding Window Median [Hard] 472 | > Similarity distance: 0.4941 473 | ##### Similarities 474 | 475 | - Both questions involve manipulating an array of numbers. 476 | - Both questions require finding the median of a subset of the array. 477 | ##### Differences 478 | 479 | - Question 462 involves finding the minimum number of moves to make all array elements equal, while question 480 involves finding the median of each sliding window in the array. 480 | - Question 462 is classified as medium difficulty, while question 480 is classified as hard difficulty. 481 | ##### New Insights in 480 Sliding Window Median [Hard] 482 | 483 | - Question 462 teaches us how to minimize the number of moves required to equalize array elements. 484 | - Question 480 teaches us how to efficiently find the median of sliding windows in an array. 485 | 486 | 487 | --- 488 | # 6. From 4 Median of Two Sorted Arrays [Hard] to 571 Find Median Given Frequency of Numbers [Hard] 489 | > Similarity Distance: 0.4846 490 | 491 | ### >> Reminder: 4 Median of Two Sorted Arrays [Hard] 492 | Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. 493 | ##### Optimal Python solution: 494 | ```python 495 | class Solution: 496 | def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: 497 | merged = sorted(nums1 + nums2) 498 | n = len(merged) 499 | if n % 2 == 0: 500 | return (merged[n // 2 - 1] + merged[n // 2]) / 2 501 | else: 502 | return merged[n // 2] 503 | ``` 504 | The essence of this problem is to merge and sort two sorted arrays to find the median. 505 | 506 | ### >> 571 Find Median Given Frequency of Numbers [Hard] 507 | Given a list of numbers and their frequencies, find the median of the numbers. 508 | ##### Sample input: 509 | [1, 3, 2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5] 510 | ##### Sample output: 511 | 4 512 | 513 | ##### Questions to ask to clarify requirements: 514 | 515 | - What is the maximum number of elements in the list? 516 | - Can the list contain negative numbers? 517 | - Can the list be empty? 518 | 519 | ##### Optimal Python solution: 520 | ```python 521 | def findMedian(nums): 522 | freq = [] 523 | for i in range(len(nums)): 524 | freq.extend([nums[i][0]] * nums[i][1]) 525 | freq.sort() 526 | n = len(freq) 527 | if n % 2 == 0: 528 | return (freq[n // 2 - 1] + freq[n // 2]) / 2 529 | else: 530 | return freq[n // 2] 531 | ``` 532 | ##### Time complexity: 533 | O(nlogn) 534 | ##### Space complexity: 535 | O(n) 536 | ##### Notes: 537 | 538 | - Create a frequency list from the given numbers and frequencies 539 | - Sort the frequency list 540 | - Find the median of the sorted list 541 | 542 | - Use the built-in sort function in Python to sort the frequency list. 543 | - Handle the case when the number of elements is even by taking the average of the middle two elements. 544 | 545 | - Handling the case when the number of elements is even 546 | 547 | - Using a brute force approach to find the median 548 | 549 | ### >> Comparison: 4 Median of Two Sorted Arrays [Hard] *VS* 571 Find Median Given Frequency of Numbers [Hard] 550 | > Similarity distance: 0.4846 551 | ##### Similarities 552 | 553 | - Both questions are related to finding the median of a set of numbers. 554 | - Both questions are classified as 'Hard' level difficulty. 555 | ##### Differences 556 | 557 | - Question 4 requires finding the median of two sorted arrays, while question 571 requires finding the median given the frequency of numbers. 558 | - Question 4 involves working with arrays, while question 571 involves working with frequency counts. 559 | - Question 4 has a time complexity requirement of O(log(m+n)), while question 571 does not have a specific time complexity requirement. 560 | ##### New Insights in 571 Find Median Given Frequency of Numbers [Hard] 561 | 562 | - Question 4 introduces the concept of merging two sorted arrays to find the median. 563 | - Question 571 introduces the concept of calculating the median given the frequency of numbers. 564 | 565 | --------------------------------------------------------------------------------