├── 2024 ├── 121. Best Time to Buy and Sell Stock │ ├── description.md │ ├── photos │ │ └── 1.jpg │ └── solution.ts ├── 122. Best Time to Buy and Sell Stock II │ ├── bestSolution.ts │ ├── description.md │ ├── photos │ │ └── 1.jpg │ └── solution.ts ├── 134. Gas Station │ ├── description.md │ └── solution.ts ├── 169. Majority Element │ ├── aiSolution.ts │ ├── description.md │ ├── mySolution.ts │ └── photos │ │ └── 1.jpg ├── 189. Rotate Array │ ├── aiSolution.ts │ ├── description.md │ ├── mySolution.ts │ └── photos │ │ └── 1.jpg ├── 238.Product of Array Except Self │ ├── description.md │ ├── photos │ │ ├── init.jpg │ │ ├── solution1.jpg │ │ └── solution2.jpg │ ├── solution1.ts │ └── solution2.ts ├── 26.Remove Duplicates From Sorted Array │ ├── aiSolution.ts │ ├── description.md │ ├── mySolution.ts │ └── photos │ │ └── 1.jpg ├── 27.Remove Element │ ├── aiSolution.ts │ ├── description.md │ ├── mySolution.ts │ └── photos │ │ └── 1.jpg ├── 274. H-Index │ ├── description.md │ └── solution.ts ├── 380.Insert Delete GetRandom O(1) │ ├── description.md │ └── solution.ts ├── 45. Jump Game II │ ├── description.md │ ├── referAnswer.js │ └── solution.ts ├── 55. Jump Game │ ├── description.md │ ├── photos │ │ └── 1.jpg │ └── solution.ts ├── 80. Remove Duplicates from Sorted Array II(Medium) │ ├── aiSolution.ts │ ├── description.md │ ├── mySolution.ts │ └── photos │ │ └── 1.jpg └── 88. Merge Sorted Array │ ├── aiSolution.ts │ ├── description.md │ ├── mySolution.ts │ └── photos │ ├── 01.jpg │ └── 02.jpg └── README.md /2024/121. Best Time to Buy and Sell Stock/description.md: -------------------------------------------------------------------------------- 1 | # 121. Best Time to Buy and Sell Stock 2 | 3 | **Difficulty:** Easy 4 | 5 | ## Problem Statement 6 | 7 | You are given an array `prices` where `prices[i]` is the price of a given stock on the ith day. You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock. 8 | 9 | Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0. 10 | 11 | ## Examples 12 | 13 | ### Example 1: 14 | 15 | **Input:** `prices = [7,1,5,3,6,4]` 16 | **Output:** `5` 17 | **Explanation:** Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6 - 1 = 5. Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell. 18 | 19 | ### Example 2: 20 | 21 | **Input:** `prices = [7,6,4,3,1]` 22 | **Output:** `0` 23 | **Explanation:** In this case, no transactions are done and the max profit = 0. 24 | 25 | ## Constraints 26 | 27 | - `1 <= prices.length <= 10^5` 28 | - `0 <= prices[i] <= 10^4` 29 | -------------------------------------------------------------------------------- /2024/121. Best Time to Buy and Sell Stock/photos/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/121. Best Time to Buy and Sell Stock/photos/1.jpg -------------------------------------------------------------------------------- /2024/121. Best Time to Buy and Sell Stock/solution.ts: -------------------------------------------------------------------------------- 1 | function maxProfit(prices: number[]): number { 2 | let buy:number = prices[0]; 3 | let profit:number = 0; 4 | for(let index:number = 1 ; index < prices.length ; index++){ 5 | if(prices[index] < buy){ 6 | buy = prices[index] 7 | }else if(prices[index] - buy > profit){ 8 | profit = prices[index] - buy; 9 | } 10 | } 11 | return profit; 12 | }; 13 | 14 | /** 15 | * To solve the "Best Time to Buy and Sell Stock" problem efficiently, you can use a single-pass algorithm with a time complexity of O(n). Here's the approach: 16 | 17 | ### Algorithm 18 | 19 | 1. **Initialize Variables**: 20 | - Set `min_price` to a very high value (e.g., infinity). 21 | - Set `max_profit` to 0. 22 | 23 | 2. **Iterate Through Prices**: 24 | - For each price in the array: 25 | - Update `min_price` to be the minimum of the current `min_price` and the current price. 26 | - Calculate the potential profit by subtracting `min_price` from the current price. 27 | - Update `max_profit` to be the maximum of the current `max_profit` and the calculated potential profit. 28 | 29 | 3. **Return `max_profit`** after completing the iteration. 30 | 31 | ### Python Code Example 32 | 33 | ```python 34 | def maxProfit(prices): 35 | min_price = float('inf') 36 | max_profit = 0 37 | 38 | for price in prices: 39 | min_price = min(min_price, price) 40 | profit = price - min_price 41 | max_profit = max(max_profit, profit) 42 | 43 | return max_profit 44 | ``` 45 | 46 | ### Explanation of the Code 47 | 48 | - The loop iterates through each price once (O(n) time complexity). 49 | - The `min_price` keeps track of the lowest price encountered so far. 50 | - The `max_profit` is updated based on the difference between the current price and `min_price`. 51 | 52 | ### Example 53 | 54 | For the input `prices = [7, 1, 5, 3, 6, 4]`: 55 | - On day 1, `min_price` is updated to 1. 56 | - On day 5, `max_profit` becomes 5 (6 - 1). 57 | 58 | This method ensures that you achieve the maximum profit with minimal computational resources. 59 | * 60 | */ -------------------------------------------------------------------------------- /2024/122. Best Time to Buy and Sell Stock II/bestSolution.ts: -------------------------------------------------------------------------------- 1 | function maxProfit(prices: number[]): number { 2 | let profit = 0; 3 | 4 | for (let i = 1; i < prices.length; i++) { 5 | // If the price today is greater than the price yesterday, add the difference to profit 6 | if (prices[i] > prices[i - 1]) { 7 | profit += prices[i] - prices[i - 1]; 8 | } 9 | } 10 | 11 | return profit; 12 | } 13 | -------------------------------------------------------------------------------- /2024/122. Best Time to Buy and Sell Stock II/description.md: -------------------------------------------------------------------------------- 1 | # Best Time to Buy and Sell Stock II 2 | 3 | ## Problem Description 4 | 5 | You are given an integer array `prices` where `prices[i]` is the price of a given stock on the ith day. 6 | 7 | On each day, you may decide to buy and/or sell the stock. You can only hold at most one share of the stock at any time. However, you can buy it then immediately sell it on the same day. 8 | 9 | Find and return the maximum profit you can achieve. 10 | 11 | ## Examples 12 | 13 | ### Example 1 14 | **Input:** 15 | ```plaintext 16 | prices = [7, 1, 5, 3, 6, 4] 17 | -------------------------------------------------------------------------------- /2024/122. Best Time to Buy and Sell Stock II/photos/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/122. Best Time to Buy and Sell Stock II/photos/1.jpg -------------------------------------------------------------------------------- /2024/122. Best Time to Buy and Sell Stock II/solution.ts: -------------------------------------------------------------------------------- 1 | function maxProfit(prices: number[]): number { 2 | let buy:number = prices[0]; 3 | let profit:number = 0; 4 | for(let i:number = 0 ; i < prices.length ; i++){ 5 | if(buy > prices[i]){ 6 | buy = prices[i] 7 | }else if(buy < prices[i]){ 8 | let difference:number = prices[i] - buy; 9 | profit = profit + difference; 10 | buy = prices[i]; 11 | } 12 | } 13 | return profit; 14 | }; 15 | 16 | /** 17 | * 18 | * Your solution to the problem is on the right track, but there are some areas for improvement: 19 | 20 | ### Issues in Your Code 21 | 1. **Resetting `buy` Price:** In your current implementation, you reset the `buy` variable to the selling price after a sale, which doesn't accurately represent the buy price for the next transaction. You should only update `buy` if you find a lower price before a sale. 22 | 23 | 2. **Logic for Buying and Selling:** You don't need to track `buy` in this way. Instead, you can simply add the profit for every price increase. 24 | 25 | ### Improved Solution 26 | Here’s an optimized version of your function that follows a simpler approach: 27 | 28 | ```typescript 29 | function maxProfit(prices: number[]): number { 30 | let profit = 0; 31 | 32 | for (let i = 1; i < prices.length; i++) { 33 | // If the price today is greater than the price yesterday, add the difference to profit 34 | if (prices[i] > prices[i - 1]) { 35 | profit += prices[i] - prices[i - 1]; 36 | } 37 | } 38 | 39 | return profit; 40 | } 41 | ``` 42 | 43 | ### Explanation 44 | - **Iterate through the array:** Start from the second day and compare the price with the previous day. 45 | - **Calculate profit:** Whenever the current price is greater than the previous day's price, add the difference to the profit. This simulates buying the stock the day before and selling it today. 46 | 47 | ### Time Complexity 48 | - The time complexity remains \(O(n)\), where \(n\) is the length of the prices array. This is optimal for this problem. 49 | 50 | ### Conclusion 51 | Your original approach had some good ideas, but simplifying the logic can help avoid potential issues and make the code cleaner. The revised solution accurately captures the maximum profit by taking advantage of every price increase. 52 | * 53 | */ -------------------------------------------------------------------------------- /2024/134. Gas Station/description.md: -------------------------------------------------------------------------------- 1 | Here's the problem description formatted in Markdown: 2 | 3 | ```markdown 4 | ## 134. Gas Station 5 | 6 | **Difficulty:** Medium 7 | **Topics:** Companies 8 | 9 | There are `n` gas stations along a circular route, where the amount of gas at the `i-th` station is `gas[i]`. 10 | 11 | You have a car with an unlimited gas tank and it costs `cost[i]` of gas to travel from the `i-th` station to its next (`i + 1-th`) station. You begin the journey with an empty tank at one of the gas stations. 12 | 13 | Given two integer arrays `gas` and `cost`, return the starting gas station's index if you can travel around the circuit once in the clockwise direction; otherwise, return `-1`. If there exists a solution, it is guaranteed to be unique. 14 | 15 | ### Example 1: 16 | 17 | **Input:** 18 | ```plaintext 19 | gas = [1,2,3,4,5] 20 | cost = [3,4,5,1,2] 21 | ``` 22 | **Output:** `3` 23 | 24 | **Explanation:** 25 | Start at station 3 (index 3) and fill up with 4 units of gas. Your tank = 0 + 4 = 4. 26 | Travel to station 4. Your tank = 4 - 1 + 5 = 8. 27 | Travel to station 0. Your tank = 8 - 2 + 1 = 7. 28 | Travel to station 1. Your tank = 7 - 3 + 2 = 6. 29 | Travel to station 2. Your tank = 6 - 4 + 3 = 5. 30 | Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3. 31 | Therefore, return 3 as the starting index. 32 | 33 | ### Example 2: 34 | 35 | **Input:** 36 | ```plaintext 37 | gas = [2,3,4] 38 | cost = [3,4,3] 39 | ``` 40 | **Output:** `-1` 41 | 42 | **Explanation:** 43 | You can't start at station 0 or 1, as there is not enough gas to travel to the next station. 44 | Let's start at station 2 and fill up with 4 units of gas. Your tank = 0 + 4 = 4. 45 | Travel to station 0. Your tank = 4 - 3 + 2 = 3. 46 | Travel to station 1. Your tank = 3 - 3 + 3 = 3. 47 | You cannot travel back to station 2, as it requires 4 units of gas but you only have 3. 48 | Therefore, you can't travel around the circuit once no matter where you start. 49 | 50 | ### Constraints: 51 | - `n == gas.length == cost.length` 52 | - `1 <= n <= 10^5` 53 | - `0 <= gas[i], cost[i] <= 10^4` 54 | ``` -------------------------------------------------------------------------------- /2024/134. Gas Station/solution.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/134. Gas Station/solution.ts -------------------------------------------------------------------------------- /2024/169. Majority Element/aiSolution.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Please refer to mySolution.ts.This is the best solution 3 | */ -------------------------------------------------------------------------------- /2024/169. Majority Element/description.md: -------------------------------------------------------------------------------- 1 | # 169. Majority Element 2 | 3 | **Status:** Solved 4 | **Difficulty:** Easy 5 | 6 | ## Topics 7 | - Algorithms 8 | - Array 9 | 10 | ## Problem Statement 11 | 12 | Given an array `nums` of size `n`, return the majority element. 13 | 14 | The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array. 15 | 16 | ### Examples 17 | 18 | **Example 1:** 19 | 20 | Input: `nums = [3,2,3]` 21 | Output: `3` 22 | 23 | **Example 2:** 24 | 25 | Input: `nums = [2,2,1,1,1,2,2]` 26 | Output: `2` 27 | 28 | ### Constraints 29 | 30 | - `n == nums.length` 31 | - `1 <= n <= 5 * 10^4` 32 | - `-10^9 <= nums[i] <= 10^9` 33 | 34 | ### Follow-up 35 | 36 | Could you solve the problem in linear time and in O(1) space? 37 | -------------------------------------------------------------------------------- /2024/169. Majority Element/mySolution.ts: -------------------------------------------------------------------------------- 1 | function majorityElement(nums: number[]): number { 2 | let count:number = 0; 3 | let candidate:number = 0; 4 | 5 | for(let index = 0 ; index < nums.length ; index++){ 6 | if(count == 0){ 7 | candidate = nums[index]; 8 | } 9 | 10 | if(nums[index] == candidate){ 11 | count++; 12 | }else{ 13 | count--; 14 | } 15 | } 16 | 17 | return candidate; 18 | }; 19 | 20 | 21 | /** 22 | * 23 | * Your solution implements the Boyer-Moore Voting Algorithm, which is efficient and meets the requirements for linear time and O(1) space. Here are a few points of advice and observations: 24 | 25 | 1. **Clarity**: Your code is clear and straightforward. Consider adding comments to explain the logic, especially for those unfamiliar with the algorithm. 26 | 27 | 2. **Type Safety**: Since TypeScript is used, you can specify the return type of the function directly in the function signature, which you already did. Good job! 28 | 29 | 3. **Edge Cases**: While the problem states that a majority element always exists, you might consider validating inputs in real-world applications to ensure robustness. 30 | 31 | Here’s a slightly modified version with comments for clarity: 32 | 33 | ```typescript 34 | function majorityElement(nums: number[]): number { 35 | let count: number = 0; 36 | let candidate: number = 0; 37 | 38 | for (let index = 0; index < nums.length; index++) { 39 | if (count === 0) { 40 | candidate = nums[index]; // Set the new candidate 41 | } 42 | 43 | // Increase or decrease count based on the current candidate 44 | if (nums[index] === candidate) { 45 | count++; 46 | } else { 47 | count--; 48 | } 49 | } 50 | 51 | return candidate; // Return the candidate as the majority element 52 | } 53 | ``` 54 | 55 | Overall, your implementation is solid! Great job! 56 | * 57 | */ -------------------------------------------------------------------------------- /2024/169. Majority Element/photos/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/169. Majority Element/photos/1.jpg -------------------------------------------------------------------------------- /2024/189. Rotate Array/aiSolution.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Your solution is already quite efficient and commonly used for this problem. 3 | */ -------------------------------------------------------------------------------- /2024/189. Rotate Array/description.md: -------------------------------------------------------------------------------- 1 | # 189. Rotate Array 2 | **Medium** 3 | 4 | ## Topics 5 | - Array 6 | - Two Pointers 7 | - Math 8 | 9 | ## Companies 10 | - Amazon 11 | - Microsoft 12 | - Google 13 | 14 | ## Hint 15 | Given an integer array `nums`, rotate the array to the right by `k` steps, where `k` is non-negative. 16 | 17 | ### Example 1: 18 | **Input:** `nums = [1,2,3,4,5,6,7], k = 3` 19 | **Output:** `[5,6,7,1,2,3,4]` 20 | **Explanation:** 21 | - rotate 1 step to the right: `[7,1,2,3,4,5,6]` 22 | - rotate 2 steps to the right: `[6,7,1,2,3,4,5]` 23 | - rotate 3 steps to the right: `[5,6,7,1,2,3,4]` 24 | 25 | ### Example 2: 26 | **Input:** `nums = [-1,-100,3,99], k = 2` 27 | **Output:** `[3,99,-1,-100]` 28 | **Explanation:** 29 | - rotate 1 step to the right: `[99,-1,-100,3]` 30 | - rotate 2 steps to the right: `[3,99,-1,-100]` 31 | 32 | ## Constraints: 33 | - `1 <= nums.length <= 10^5` 34 | - `-2^31 <= nums[i] <= 2^31 - 1` 35 | - `0 <= k <= 10^5` 36 | 37 | ## Follow up: 38 | Try to come up with as many solutions as you can. There are at least three different ways to solve this problem. Could you do it in-place with O(1) extra space? 39 | -------------------------------------------------------------------------------- /2024/189. Rotate Array/mySolution.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Do not return anything, modify nums in-place instead. 3 | */ 4 | function rotate(nums: number[], k: number): void { 5 | k = k % nums.length; 6 | reverse(nums,0,nums.length-1); 7 | reverse(nums,0,k-1); 8 | reverse(nums,k,nums.length-1); 9 | }; 10 | 11 | function reverse(nums:number[],start:number,end:number) :void{ 12 | while(start < end){ 13 | let temp:number = nums[start]; 14 | nums[start] = nums[end]; 15 | nums[end] = temp; 16 | 17 | start++; 18 | end--; 19 | } 20 | } 21 | 22 | /** 23 | * Your solution effectively rotates the array in-place using a three-step reversal approach, which is both time-efficient and space-efficient. Here’s a brief breakdown of your implementation and some suggestions: 24 | 25 | ### Code Review: 26 | 1. **Clarity:** The function names (`rotate` and `reverse`) are clear and convey their purpose well. 27 | 2. **In-Place Modification:** You correctly modify the array without using additional space, adhering to the problem constraints. 28 | 3. **Modulus Operation:** Using `k = k % nums.length` is essential to handle cases where `k` exceeds the length of the array. 29 | 30 | ### Suggestions: 31 | - **Edge Cases:** Consider adding checks for edge cases, like when `k` is `0` or when `nums` is empty, though your current implementation handles it well since reversing an empty array or a single-element array has no effect. 32 | - **Commenting:** You might want to add comments within the code for clarity, especially in the `reverse` function, to explain the swapping process. 33 | 34 | ### Example Usage: 35 | You could also include a simple example usage for testing: 36 | ```typescript 37 | let nums = [1, 2, 3, 4, 5, 6, 7]; 38 | let k = 3; 39 | rotate(nums, k); 40 | console.log(nums); // Output: [5, 6, 7, 1, 2, 3, 4] 41 | ``` 42 | 43 | Overall, your solution is solid! If you have specific areas you'd like feedback on or any questions, let me know! 44 | */ -------------------------------------------------------------------------------- /2024/189. Rotate Array/photos/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/189. Rotate Array/photos/1.jpg -------------------------------------------------------------------------------- /2024/238.Product of Array Except Self/description.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/238.Product of Array Except Self/description.md -------------------------------------------------------------------------------- /2024/238.Product of Array Except Self/photos/init.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/238.Product of Array Except Self/photos/init.jpg -------------------------------------------------------------------------------- /2024/238.Product of Array Except Self/photos/solution1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/238.Product of Array Except Self/photos/solution1.jpg -------------------------------------------------------------------------------- /2024/238.Product of Array Except Self/photos/solution2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/238.Product of Array Except Self/photos/solution2.jpg -------------------------------------------------------------------------------- /2024/238.Product of Array Except Self/solution1.ts: -------------------------------------------------------------------------------- 1 | function productExceptSelf(nums: number[]): number[] { 2 | // solution1: 3 | let n:number = nums.length; 4 | let pre:number[] = new Array(n); 5 | let suff:number[] = new Array(n); 6 | let ans:number[] = new Array(n); 7 | 8 | pre[0] = 1; 9 | suff[n-1] = 1; 10 | 11 | for(let index:number = 1;index=0;index--){ 16 | suff[index] = suff[index+1] * nums[index+1]; 17 | } 18 | 19 | for(let index:number = 0;index=0;index--){ 15 | ans[index] *= curr; 16 | curr *= nums[index]; 17 | } 18 | return ans; 19 | }; -------------------------------------------------------------------------------- /2024/26.Remove Duplicates From Sorted Array/aiSolution.ts: -------------------------------------------------------------------------------- 1 | function removeDuplicates(nums: number[]): number { 2 | let writeIndex = 1; 3 | 4 | // Loop from the second element and check for unique values 5 | for (let current = 1; current < nums.length; current++) { 6 | // Check if the current value is different from the previous one 7 | if (nums[current] !== nums[current - 1]) { 8 | nums[writeIndex++] = nums[current]; // Write the unique element and increment 9 | } 10 | } 11 | 12 | return writeIndex; 13 | } 14 | 15 | /** 16 | * Changes and Explanation: 17 | For Loop: 18 | 19 | I replaced the while loop with a for loop to avoid the extra overhead of manually incrementing the left variable. This is a micro-optimization and typically runs faster in most JavaScript engines. 20 | Inline Increment: 21 | 22 | The writeIndex++ inside the assignment is an inline operation, which may provide minor performance benefits in terms of reduced instruction count. 23 | Readability and Simplicity: 24 | 25 | The code is simplified, which reduces overhead in terms of maintenance without sacrificing performance. 26 | Final Consideration: 27 | For arrays of large sizes, you won’t be able to reduce the complexity beyond O(n) since every element has to be checked at least once. The current implementation is optimal under the problem's constraints. Any further speed increase would depend on how efficiently JavaScript's runtime handles loops and memory, which is out of your control. 28 | */ -------------------------------------------------------------------------------- /2024/26.Remove Duplicates From Sorted Array/description.md: -------------------------------------------------------------------------------- 1 | 2 | # Problem: Remove Duplicates from Sorted Array 3 | 4 | **Difficulty:** Easy 5 | **Status:** Solved 6 | 7 | ## Problem Statement 8 | 9 | Given an integer array `nums` sorted in non-decreasing order, remove the duplicates **in-place** such that each unique element appears only once. The relative order of the elements should be kept the same. Then return the number of unique elements in `nums`. 10 | 11 | Consider the number of unique elements in `nums` to be `k`. To get accepted, you need to do the following things: 12 | 13 | 1. Change the array `nums` such that the first `k` elements of `nums` contain the unique elements in the order they were present in `nums` initially. 14 | 2. The remaining elements of `nums` are not important, as well as the size of `nums`. 15 | 3. Return `k`. 16 | 17 | ### Custom Judge: 18 | 19 | The judge will test your solution with the following code: 20 | 21 | ```java 22 | int[] nums = [...]; // Input array 23 | int[] expectedNums = [...]; // The expected answer with correct length 24 | 25 | int k = removeDuplicates(nums); // Calls your implementation 26 | 27 | assert k == expectedNums.length; 28 | for (int i = 0; i < k; i++) { 29 | assert nums[i] == expectedNums[i]; 30 | } 31 | ``` 32 | 33 | If all assertions pass, then your solution will be accepted. 34 | 35 | ## Example 1: 36 | 37 | - **Input:** `nums = [1, 1, 2]` 38 | - **Output:** `2, nums = [1, 2, _]` 39 | - **Explanation:** 40 | Your function should return `k = 2`, with the first two elements of `nums` being `1` and `2` respectively. It does not matter what you leave beyond the returned `k` (hence they are underscores). 41 | 42 | ## Example 2: 43 | 44 | - **Input:** `nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4]` 45 | - **Output:** `5, nums = [0, 1, 2, 3, 4, _, _, _, _, _]` 46 | - **Explanation:** 47 | Your function should return `k = 5`, with the first five elements of `nums` being `0, 1, 2, 3, and 4` respectively. It does not matter what you leave beyond the returned `k` (hence they are underscores). 48 | 49 | -------------------------------------------------------------------------------- /2024/26.Remove Duplicates From Sorted Array/mySolution.ts: -------------------------------------------------------------------------------- 1 | function removeDuplicates(nums: number[]): number { 2 | let left:number = 1; 3 | let right:number = 1; 4 | while(left < nums.length){ 5 | if(nums[left] != nums[left - 1]){ 6 | nums[right] = nums[left]; 7 | right++; 8 | } 9 | left++; 10 | } 11 | return right; 12 | }; 13 | 14 | /** 15 | * 16 | * Thanks for the clarification! Given the constraints that the array is always non-empty and has a length between 1 and 30,000, you don't need to worry about handling the empty array case. This simplifies things, and your approach is already optimal. 17 | 18 | ### **Key Observations:** 19 | - Since the array is guaranteed to be sorted and always has at least one element, your current approach is well-suited for the problem. 20 | - The constraints ensure that the input will be valid, so you can focus on maintaining clean and efficient code. 21 | 22 | ### **Updated Suggestions Without Edge Case Handling**: 23 | 24 | 1. **Variable Names**: 25 | - As mentioned earlier, you could still consider more descriptive names for readability, like `current` and `writeIndex`, which indicate their purpose more clearly than `left` and `right`. 26 | 27 | Example: 28 | ```typescript 29 | function removeDuplicates(nums: number[]): number { 30 | let current: number = 1; 31 | let writeIndex: number = 1; 32 | while (current < nums.length) { 33 | if (nums[current] !== nums[current - 1]) { 34 | nums[writeIndex] = nums[current]; 35 | writeIndex++; 36 | } 37 | current++; 38 | } 39 | return writeIndex; 40 | } 41 | ``` 42 | 43 | 2. **Commenting**: 44 | - Adding comments for better code readability can help future maintainability, even though it's a simple algorithm. 45 | 46 | ### **Final Code Suggestion**: 47 | 48 | ```typescript 49 | function removeDuplicates(nums: number[]): number { 50 | let current: number = 1; // Start checking from the second element 51 | let writeIndex: number = 1; // This tracks where to write the next unique element 52 | 53 | // Traverse the array from the second element to the end 54 | while (current < nums.length) { 55 | // If current element is different from the previous one, it's unique 56 | if (nums[current] !== nums[current - 1]) { 57 | nums[writeIndex] = nums[current]; // Place the unique element at writeIndex 58 | writeIndex++; // Move the write index to the next position 59 | } 60 | current++; // Move to the next element 61 | } 62 | 63 | // Return the number of unique elements 64 | return writeIndex; 65 | } 66 | ``` 67 | 68 | ### **Explanation**: 69 | - **O(n) Time Complexity**: The array is traversed once, making the solution optimal. 70 | - **O(1) Space Complexity**: The algorithm uses constant extra space, which fits the problem requirements. 71 | 72 | ### **Conclusion**: 73 | Your solution is already well-optimized, and since you're working within well-defined constraints, no need to overcomplicate. The main recommendation is improving variable naming for clarity, but functionally your solution is spot-on. 74 | */ -------------------------------------------------------------------------------- /2024/26.Remove Duplicates From Sorted Array/photos/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/26.Remove Duplicates From Sorted Array/photos/1.jpg -------------------------------------------------------------------------------- /2024/27.Remove Element/aiSolution.ts: -------------------------------------------------------------------------------- 1 | function removeElement(nums: number[], val: number): number { 2 | let left: number = 0; 3 | let right: number = nums.length - 1; 4 | 5 | while (left <= right) { 6 | if (nums[left] === val) { 7 | // Swap with the element at 'right' if 'left' points to 'val' 8 | [nums[left], nums[right]] = [nums[right], nums[left]]; 9 | right--; // Move 'right' pointer left 10 | } else { 11 | left++; // Move 'left' pointer right 12 | } 13 | } 14 | 15 | return left; // 'left' now points to the count of elements not equal to 'val' 16 | } 17 | -------------------------------------------------------------------------------- /2024/27.Remove Element/description.md: -------------------------------------------------------------------------------- 1 | # 27. Remove Element 2 | 3 | ## Difficulty 4 | Easy 5 | 6 | ## Topics 7 | - Array 8 | - Two Pointers 9 | 10 | ## Description 11 | Given an integer array `nums` and an integer `val`, remove all occurrences of `val` in `nums` in-place. The order of the elements may be changed. Then return the number of elements in `nums` which are not equal to `val`. 12 | 13 | Consider the number of elements in `nums` which are not equal to `val` to be `k`. To get accepted, you need to do the following things: 14 | 15 | - Change the array `nums` such that the first `k` elements of `nums` contain the elements which are not equal to `val`. The remaining elements of `nums` are not important as well as the size of `nums`. 16 | - Return `k`. 17 | 18 | ## Custom Judge 19 | The judge will test your solution with the following code: 20 | 21 | ```java 22 | int[] nums = [...]; // Input array 23 | int val = ...; // Value to remove 24 | int[] expectedNums = [...]; // The expected answer with correct length. 25 | // It is sorted with no values equaling val. 26 | 27 | int k = removeElement(nums, val); // Calls your implementation 28 | 29 | assert k == expectedNums.length; 30 | sort(nums, 0, k); // Sort the first k elements of nums 31 | for (int i = 0; i < actualLength; i++) { 32 | assert nums[i] == expectedNums[i]; 33 | } 34 | 35 | 36 | https://leetcode.com/problems/remove-element/description/?envType=study-plan-v2&envId=top-interview-150 37 | -------------------------------------------------------------------------------- /2024/27.Remove Element/mySolution.ts: -------------------------------------------------------------------------------- 1 | function removeElement(nums: number[], val: number): number { 2 | let left:number = 0; 3 | let right:number = nums.length - 1; 4 | 5 | while(left<=right){ 6 | if(nums[left] != val){ 7 | left++; 8 | }else{ 9 | if(nums[right] == val){ 10 | right--; 11 | }else{ 12 | let temporaryNum:number = nums[left]; 13 | nums[left] = nums[right]; 14 | nums[right] = temporaryNum; 15 | left++; 16 | right--; 17 | } 18 | } 19 | } 20 | 21 | let k:number = right+1; 22 | return k; 23 | }; 24 | 25 | /** 26 | * Your implementation of the removeElement function uses a two-pointer technique, which is a good approach. Here’s an analysis along with some suggestions for improvement: 27 | 28 | Analysis 29 | Logic: 30 | 31 | You have a left pointer (left) that scans from the start of the array and a right pointer (right) that scans from the end. 32 | If the element at left is not equal to val, it simply increments left. 33 | If the element at left is equal to val, it checks the right pointer. If right points to another val, it decrements right. 34 | If right points to a different value, you swap the values at left and right, then move both pointers inward. 35 | Final Value of k: 36 | 37 | You calculate k as right + 1, which gives the count of elements not equal to val. This is correct because right stops at the last non-val index. 38 | Suggestions for Improvement 39 | Redundant Checks: 40 | 41 | You can simplify the code by removing the second else condition. When you find a val at left, you can swap directly with right, and handle both pointer increments together. This will make the code cleaner. 42 | End Condition: 43 | 44 | Since you’re using a while loop with the condition left <= right, you should ensure that right doesn’t go below left. You can simplify by checking the condition on the next loop iteration. 45 | Code Readability: 46 | 47 | Adding comments or improving variable names can help others (and your future self) understand the code more quickly. 48 | */ -------------------------------------------------------------------------------- /2024/27.Remove Element/photos/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/27.Remove Element/photos/1.jpg -------------------------------------------------------------------------------- /2024/274. H-Index/description.md: -------------------------------------------------------------------------------- 1 | ## 274. H-Index 2 | 3 | **Difficulty:** Medium 4 | 5 | ### Topics 6 | - Algorithms 7 | - Sorting 8 | 9 | ### Companies 10 | - Google 11 | - Amazon 12 | - Facebook 13 | 14 | ### Problem Statement 15 | Given an array of integers `citations` where `citations[i]` is the number of citations a researcher received for their ith paper, return the researcher's h-index. 16 | 17 | According to the definition of h-index on Wikipedia: The h-index is defined as the maximum value of `h` such that the given researcher has published at least `h` papers that have each been cited at least `h` times. 18 | 19 | ### Examples 20 | 21 | #### Example 1: 22 | **Input:** `citations = [3,0,6,1,5]` 23 | **Output:** `3` 24 | **Explanation:** [3,0,6,1,5] means the researcher has 5 papers in total and each of them had received 3, 0, 6, 1, 5 citations respectively. Since the researcher has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations each, their h-index is 3. 25 | 26 | #### Example 2: 27 | **Input:** `citations = [1,3,1]` 28 | **Output:** `1` 29 | 30 | ### Constraints 31 | - `n == citations.length` 32 | - `1 <= n <= 5000` 33 | - `0 <= citations[i] <= 1000` 34 | -------------------------------------------------------------------------------- /2024/274. H-Index/solution.ts: -------------------------------------------------------------------------------- 1 | function hIndex(citations: number[]): number { 2 | citations.sort((a,b) => a-b); 3 | let length:number = citations.length; 4 | for(let index:number = 0;index a - b); // Sort citations in ascending order 30 | const n: number = citations.length; // Get the number of papers 31 | 32 | for (let index: number = 0; index < n; index++) { 33 | // Check if the number of papers left is less than or equal to citations at this index 34 | if (n - index <= citations[index]) { 35 | return n - index; // Return the h-index 36 | } 37 | } 38 | 39 | return 0; // Return 0 if no h-index is found 40 | } 41 | ``` 42 | 43 | Overall, your implementation is effective and meets the problem's requirements! 44 | */ -------------------------------------------------------------------------------- /2024/380.Insert Delete GetRandom O(1)/description.md: -------------------------------------------------------------------------------- 1 | # 380. Insert Delete GetRandom O(1) 2 | 3 | ## Problem Statement 4 | 5 | Implement the `RandomizedSet` class: 6 | 7 | - `RandomizedSet()`: Initializes the `RandomizedSet` object. 8 | - `bool insert(int val)`: Inserts an item `val` into the set if not present. Returns `true` if the item was not present, `false` otherwise. 9 | - `bool remove(int val)`: Removes an item `val` from the set if present. Returns `true` if the item was present, `false` otherwise. 10 | - `int getRandom()`: Returns a random element from the current set of elements (it's guaranteed that at least one element exists when this method is called). Each element must have the same probability of being returned. 11 | 12 | You must implement the functions of the class such that each function works in average O(1) time complexity. 13 | 14 | ## Example 1 15 | 16 | **Input** 17 | ```plaintext 18 | ["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"] 19 | [[], [1], [2], [2], [], [1], [2], []] 20 | -------------------------------------------------------------------------------- /2024/380.Insert Delete GetRandom O(1)/solution.ts: -------------------------------------------------------------------------------- 1 | class RandomizedSet { 2 | private list: number[]; // Make list a class property 3 | private map: Map; // Use the Map class for better performance 4 | 5 | constructor() { 6 | this.list = []; 7 | this.map = new Map(); // Initialize the map 8 | } 9 | 10 | insert(val: number): boolean { 11 | // Check if the number is already in the map 12 | if (this.map.has(val)) { 13 | return false; // Return false if it already exists 14 | } 15 | 16 | // Insert the value 17 | this.list.push(val); // Use push to add to the end of the list 18 | this.map.set(val, this.list.length - 1); // Map the value to its index in the list 19 | return true; // Return true after insertion 20 | } 21 | 22 | remove(val: number): boolean { 23 | // Check if the number exists in the map 24 | if (!this.map.has(val)) { 25 | return false; // Return false if it doesn't exist 26 | } 27 | 28 | // Get the index of the value to be removed 29 | const index: number = this.map.get(val)!; // Use '!' to assert non-null 30 | 31 | // Move the last element to the index of the element to remove 32 | const lastElement: number = this.list[this.list.length - 1]; 33 | this.list[index] = lastElement; 34 | this.map.set(lastElement, index); // Update the index of the last element 35 | 36 | // Remove the last element from the list 37 | this.list.pop(); 38 | this.map.delete(val); // Remove the value from the map 39 | return true; // Return true after removal 40 | } 41 | 42 | getRandom(): number { 43 | const randomIndex: number = Math.floor(Math.random() * this.list.length); // Use Math.floor for an integer 44 | return this.list[randomIndex]; // Return a random element from the list 45 | } 46 | } 47 | 48 | /** 49 | * Your RandomizedSet object will be instantiated and called as such: 50 | * var obj = new RandomizedSet(); 51 | * var param_1 = obj.insert(val); 52 | * var param_2 = obj.remove(val); 53 | * var param_3 = obj.getRandom(); 54 | */ 55 | -------------------------------------------------------------------------------- /2024/45. Jump Game II/description.md: -------------------------------------------------------------------------------- 1 | ## 45. Jump Game II 2 | 3 | **Difficulty**: Medium 4 | **Topics**: Dynamic Programming, Greedy 5 | 6 | You are given a 0-indexed array of integers `nums` of length `n`. You are initially positioned at `nums[0]`. 7 | 8 | Each element `nums[i]` represents the maximum length of a forward jump from index `i`. In other words, if you are at `nums[i]`, you can jump to any `nums[i + j]` where: 9 | 10 | - `0 <= j <= nums[i]` 11 | - `i + j < n` 12 | 13 | Return the minimum number of jumps to reach `nums[n - 1]`. The test cases are generated such that you can reach `nums[n - 1]`. 14 | 15 | ### Example 1: 16 | 17 | **Input**: `nums = [2,3,1,1,4]` 18 | **Output**: `2` 19 | **Explanation**: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index. 20 | 21 | ### Example 2: 22 | 23 | **Input**: `nums = [2,3,0,1,4]` 24 | **Output**: `2` 25 | 26 | ### Constraints: 27 | - `1 <= nums.length <= 10^4` 28 | - `0 <= nums[i] <= 1000` 29 | 30 | It's guaranteed that you can reach `nums[n - 1]`. 31 | -------------------------------------------------------------------------------- /2024/45. Jump Game II/referAnswer.js: -------------------------------------------------------------------------------- 1 | var jump = function(nums) { 2 | let near = 0, far = 0, jumps = 0; 3 | 4 | while (far < nums.length - 1) { 5 | let farthest = 0; 6 | for (let i = near; i <= far; i++) { 7 | farthest = Math.max(farthest, i + nums[i]); 8 | } 9 | near = far + 1; 10 | far = farthest; 11 | jumps++; 12 | } 13 | 14 | return jumps; 15 | }; -------------------------------------------------------------------------------- /2024/45. Jump Game II/solution.ts: -------------------------------------------------------------------------------- 1 | function jump(nums: number[]): number { 2 | let jumps:number = 0; 3 | let left:number = 0; 4 | let right:number = 0; 5 | 6 | while(right < nums.length - 1){ 7 | let farthest = 0; 8 | for(let index:number = left;index < right + 1 ; index++){ 9 | farthest = Math.max(farthest,index+nums[index]); 10 | } 11 | left = right + 1; 12 | right = farthest; 13 | jumps++; 14 | } 15 | return jumps; 16 | }; 17 | 18 | 19 | /** 20 | * Your solution for the Jump Game II problem is well-structured and effectively uses a greedy approach to find the minimum number of jumps. Here’s a breakdown of your code and some suggestions for improvement: 21 | 22 | ### Code Breakdown: 23 | 1. **Initialization**: 24 | - `jumps`: Counter for the number of jumps. 25 | - `left` and `right`: These define the current range of indices you can reach with the current number of jumps. 26 | 27 | 2. **While Loop**: 28 | - Continues until `right` reaches the last index of the array. 29 | - Inside the loop, you find the farthest point that can be reached from the current range (`left` to `right`). 30 | 31 | 3. **Inner For Loop**: 32 | - Iterates through the current range to calculate the farthest reachable index. 33 | 34 | 4. **Update Ranges**: 35 | - Sets `left` to `right + 1` and updates `right` to the `farthest` index calculated. 36 | 37 | 5. **Increment Jumps**: 38 | - Increments the `jumps` counter after processing the current range. 39 | 40 | ### Suggestions for Improvement: 41 | 1. **Avoid Unnecessary Checks**: 42 | - Instead of checking `while (right < nums.length - 1)`, you can use a condition that directly verifies the possibility of reaching the end. 43 | 44 | 2. **Refactor Inner Loop**: 45 | - You could combine the calculation of `farthest` into a single traversal without a separate loop for clarity and efficiency. 46 | 47 | 3. **Type Annotations**: 48 | - While TypeScript type annotations are great, consider using them where they enhance readability. The current usage is good, but ensure consistency. 49 | 50 | ### Example Refactoring: 51 | Here's a slightly refactored version of your code for clarity: 52 | 53 | ```typescript 54 | function jump(nums: number[]): number { 55 | let jumps: number = 0; 56 | let currentEnd: number = 0; 57 | let farthest: number = 0; 58 | 59 | for (let i = 0; i < nums.length - 1; i++) { 60 | farthest = Math.max(farthest, i + nums[i]); 61 | 62 | if (i === currentEnd) { 63 | jumps++; 64 | currentEnd = farthest; 65 | } 66 | } 67 | return jumps; 68 | } 69 | ``` 70 | 71 | ### Key Changes: 72 | - **Single Loop**: The code uses a single loop to iterate through the array. 73 | - **Early Increment**: Jumps are incremented right when the current end is reached, which simplifies the logic. 74 | 75 | ### Conclusion: 76 | Your solution is correct and efficient with a time complexity of \(O(n)\). The suggestions mainly aim to enhance clarity and maintainability. Great job overall! 77 | */ -------------------------------------------------------------------------------- /2024/55. Jump Game/description.md: -------------------------------------------------------------------------------- 1 | ## Jump Game 2 | 3 | **Difficulty:** Medium 4 | 5 | ### Problem Statement 6 | 7 | You are given an integer array `nums`. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position. 8 | 9 | Return `true` if you can reach the last index, or `false` otherwise. 10 | 11 | ### Examples 12 | 13 | **Example 1:** 14 | 15 | - **Input:** `nums = [2,3,1,1,4]` 16 | - **Output:** `true` 17 | - **Explanation:** Jump 1 step from index 0 to 1, then 3 steps to the last index. 18 | 19 | **Example 2:** 20 | 21 | - **Input:** `nums = [3,2,1,0,4]` 22 | - **Output:** `false` 23 | - **Explanation:** You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index. 24 | 25 | ### Constraints 26 | 27 | - `1 <= nums.length <= 10^4` 28 | - `0 <= nums[i] <= 10^5` 29 | -------------------------------------------------------------------------------- /2024/55. Jump Game/photos/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/55. Jump Game/photos/1.jpg -------------------------------------------------------------------------------- /2024/55. Jump Game/solution.ts: -------------------------------------------------------------------------------- 1 | function canJump(nums: number[]): boolean { 2 | let gas:number = 0; 3 | 4 | for(let index:number = 0 ; index < nums.length ; index++){ 5 | if(gas < 0){ 6 | return false; 7 | }else if(nums[index] > gas){ 8 | gas = nums[index]; 9 | } 10 | gas--; 11 | } 12 | 13 | return true; 14 | }; 15 | 16 | /** 17 | * Intuition 18 | Imagine you have a car, and you have some distance to travel (the length of the array). This car has some amount of gasoline, and as long as it has gasoline, it can keep traveling on this road (the array). Every time we move up one element in the array, we subtract one unit of gasoline. However, every time we find an amount of gasoline that is greater than our current amount, we "gas up" our car by replacing our current amount of gasoline with this new amount. We keep repeating this process until we either run out of gasoline (and return false), or we reach the end with just enough gasoline (or more to spare), in which case we return true. 19 | Note: We can let our gas tank get to zero as long as we are able to gas up at that immediate location (element in the array) that our car is currently at. 20 | 21 | Complexity 22 | Time complexity: O(n) 23 | Space complexity: O(1) 24 | * 25 | */ 26 | 27 | 28 | /** 29 | * Your solution has a good approach, but it contains a logical issue that may lead to incorrect results in some cases. Here’s a review and some suggestions for improvement: 30 | 31 | ### Current Logic 32 | 1. You are using a variable `gas` to track how many jumps you can still make. 33 | 2. For each index, if `gas` is negative, you return `false`, indicating you can't progress. 34 | 3. If `nums[index]` is greater than `gas`, you update `gas` to `nums[index]`. 35 | 4. You decrement `gas` in each iteration. 36 | 37 | ### Issues 38 | - The way you handle `gas` can lead to a situation where you incorrectly determine you can or cannot reach the end. Specifically, you only update `gas` when `nums[index]` is greater than `gas`, which may not accurately represent the maximum reachable index. 39 | 40 | ### Suggested Approach 41 | Instead of managing `gas`, a more straightforward approach is to maintain the furthest index you can reach. Here’s a revised solution: 42 | 43 | compare the maximum reachable and the maximum array index 44 | 45 | ```typescript 46 | function canJump(nums: number[]): boolean { 47 | let maxReachable: number = 0; 48 | 49 | for (let i = 0; i < nums.length; i++) { 50 | if (i > maxReachable) { 51 | return false; // If the current index is beyond the maximum reachable index 52 | } 53 | maxReachable = Math.max(maxReachable, i + nums[i]); // Update the furthest reachable index 54 | if (maxReachable >= nums.length - 1) { 55 | return true; // If we can reach the last index 56 | } 57 | } 58 | 59 | return false; // If we finish the loop without reaching the last index 60 | } 61 | ``` 62 | 63 | ### Explanation of the Revised Solution 64 | 1. **maxReachable:** This variable keeps track of the furthest index you can reach. 65 | 2. **Iteration:** For each index, you check if you're at a position that's beyond `maxReachable`. If yes, you cannot proceed, and you return `false`. 66 | 3. **Update Logic:** Update `maxReachable` to the maximum of its current value or the furthest point you can reach from the current index. 67 | 4. **Early Exit:** If at any point `maxReachable` reaches or exceeds the last index, you return `true`. 68 | 69 | ### Complexity 70 | - **Time Complexity:** O(n), where n is the length of the `nums` array. 71 | - **Space Complexity:** O(1), since you're using a constant amount of space. 72 | 73 | This revised solution should give you the correct results for all edge cases. 74 | * 75 | * 76 | * 77 | */ -------------------------------------------------------------------------------- /2024/80. Remove Duplicates from Sorted Array II(Medium)/aiSolution.ts: -------------------------------------------------------------------------------- 1 | function removeDuplicates(nums: number[]): number { 2 | if (nums.length <= 2) { 3 | return nums.length; // Return the actual length for 1 or 2 elements 4 | } 5 | 6 | let k: number = 2; // Allow at most two occurrences 7 | for (let i: number = 2; i < nums.length; i++) { 8 | // Check if current number is different from the one two positions back 9 | if (nums[i] !== nums[k - 2]) { 10 | nums[k] = nums[i]; // Place the current number in the correct position 11 | k++; 12 | } 13 | } 14 | return k; // Return the count of unique elements 15 | } 16 | -------------------------------------------------------------------------------- /2024/80. Remove Duplicates from Sorted Array II(Medium)/description.md: -------------------------------------------------------------------------------- 1 | ## 80. Remove Duplicates from Sorted Array II 2 | 3 | **Difficulty:** Medium 4 | 5 | ### Problem Statement 6 | 7 | Given an integer array `nums` sorted in non-decreasing order, remove some duplicates in-place such that each unique element appears at most twice. The relative order of the elements should be kept the same. 8 | 9 | Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array `nums`. More formally, if there are `k` elements after removing the duplicates, then the first `k` elements of `nums` should hold the final result. It does not matter what you leave beyond the first `k` elements. 10 | 11 | Return `k` after placing the final result in the first `k` slots of `nums`. 12 | 13 | **Do not allocate extra space for another array.** You must do this by modifying the input array in-place with O(1) extra memory. 14 | 15 | ### Custom Judge 16 | 17 | The judge will test your solution with the following code: 18 | 19 | ```java 20 | int[] nums = [...]; // Input array 21 | int[] expectedNums = [...]; // The expected answer with correct length 22 | 23 | int k = removeDuplicates(nums); // Calls your implementation 24 | 25 | assert k == expectedNums.length; 26 | for (int i = 0; i < k; i++) { 27 | assert nums[i] == expectedNums[i]; 28 | } 29 | -------------------------------------------------------------------------------- /2024/80. Remove Duplicates from Sorted Array II(Medium)/mySolution.ts: -------------------------------------------------------------------------------- 1 | function removeDuplicates(nums: number[]): number { 2 | if(nums.length <= 2){ 3 | return 2; 4 | } 5 | 6 | let i:number = 2; 7 | let k:number = 2; 8 | while(i < nums.length){ 9 | if(nums[i] != nums[k-2]){ 10 | nums[k] = nums[i]; 11 | k++; 12 | } 13 | i++; 14 | } 15 | return k; 16 | }; 17 | 18 | /** 19 | * Your solution to remove duplicates from a sorted array is generally good, but there are a few areas for improvement based on the constraints and the specific requirements of the problem: 20 | 21 | ### Analysis and Suggestions: 22 | 23 | 1. **Base Case Handling**: 24 | - The condition `if(nums.length <= 2) { return 2; }` is incorrect. If the array has 1 or 2 elements, you should return `nums.length`, which could be either 1 or 2. Returning 2 would not accurately reflect the number of elements in arrays of length 1. 25 | 26 | 2. **Initialization of `k`**: 27 | - The variable `k` should start at 2 since you want to allow at most two occurrences of each unique element. It's correctly initialized, but just ensure you handle it properly when returning the result. 28 | 29 | 3. **Correct Element Check**: 30 | - Your check `if(nums[i] != nums[k-2])` correctly checks if the current element can be added to the result. This ensures that each unique number appears at most twice. 31 | 32 | 4. **Use of `while` Loop**: 33 | - The use of a `while` loop is fine here, but a `for` loop might make the intent clearer since you are iterating through the array in a single pass. 34 | 35 | 5. **Time Complexity**: 36 | - Your approach runs in O(n) time complexity, which is optimal for this problem given that you need to examine each element at least once. 37 | 38 | ### Revised Code: 39 | Here’s a revised version of your code with the suggestions applied: 40 | 41 | ```typescript 42 | function removeDuplicates(nums: number[]): number { 43 | if (nums.length <= 2) { 44 | return nums.length; // Return the actual length for 1 or 2 elements 45 | } 46 | 47 | let k: number = 2; // Allow at most two occurrences 48 | for (let i: number = 2; i < nums.length; i++) { 49 | // Check if current number is different from the one two positions back 50 | if (nums[i] !== nums[k - 2]) { 51 | nums[k] = nums[i]; // Place the current number in the correct position 52 | k++; 53 | } 54 | } 55 | return k; // Return the count of unique elements 56 | } 57 | ``` 58 | 59 | ### Summary: 60 | This version clarifies the base case handling and maintains the same efficient logic for processing the array. Overall, your original approach was solid, but these adjustments ensure that it meets the problem's requirements more accurately. Would you like to explore any other aspects of this problem? 61 | */ -------------------------------------------------------------------------------- /2024/80. Remove Duplicates from Sorted Array II(Medium)/photos/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/80. Remove Duplicates from Sorted Array II(Medium)/photos/1.jpg -------------------------------------------------------------------------------- /2024/88. Merge Sorted Array/aiSolution.ts: -------------------------------------------------------------------------------- 1 | function merge(nums1: number[], m: number, nums2: number[], n: number): void { 2 | let i: number = m - 1; 3 | let j: number = n - 1; 4 | let mergeIndex: number = m + n - 1; 5 | 6 | while (j >= 0) { // Only need to check j since we can ignore leftover nums1 elements 7 | if (i >= 0 && nums1[i] > nums2[j]) { 8 | nums1[mergeIndex] = nums1[i]; 9 | i--; 10 | } else { 11 | nums1[mergeIndex] = nums2[j]; 12 | j--; 13 | } 14 | mergeIndex--; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /2024/88. Merge Sorted Array/description.md: -------------------------------------------------------------------------------- 1 | # Merge Sorted Arrays 2 | 3 | ## Problem Statement 4 | 5 | You are given two integer arrays `nums1` and `nums2`, sorted in non-decreasing order, and two integers `m` and `n`, representing the number of elements in `nums1` and `nums2` respectively. 6 | 7 | Merge `nums1` and `nums2` into a single array sorted in non-decreasing order. 8 | 9 | The final sorted array should not be returned by the function, but instead be stored inside the array `nums1`. To accommodate this, `nums1` has a length of `m + n`, where the first `m` elements denote the elements that should be merged, and the last `n` elements are set to `0` and should be ignored. `nums2` has a length of `n`. 10 | 11 | ## Examples 12 | 13 | ### Example 1: 14 | 15 | **Input:**: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 16 | **Output**: [1,2,2,3,5,6] 17 | **Explanation**: The arrays we are merging are [1,2,3] and [2,5,6]. 18 | The result of the merge is [1,2,2,3,5,6] with the underlined elements coming from nums1. 19 | 20 | ### Example 2: 21 | 22 | **Input:**: nums1 = [1], m = 1, nums2 = [], n = 0 23 | **Output**: [1] 24 | **Explanation**: The arrays we are merging are [1] and []. 25 | The result of the merge is [1]. 26 | 27 | ### Example 3: 28 | 29 | **Input:**: nums1 = [0], m = 0, nums2 = [1], n = 1 30 | **Output**: [1] 31 | **Explanation**: The arrays we are merging are [] and [1]. 32 | The result of the merge is [1]. 33 | Note that because m = 0, there are no elements in nums1. The 0 is only there to ensure the merge result can fit in nums1 34 | -------------------------------------------------------------------------------- /2024/88. Merge Sorted Array/mySolution.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Do not return anything, modify nums1 in-place instead. 3 | */ 4 | function merge(nums1: number[], m: number, nums2: number[], n: number): void { 5 | let i:number = m - 1; 6 | let j:number = n - 1; 7 | let k:number = m + n - 1; 8 | while(k>=0){ 9 | if(i>= 0 && j>= 0){ 10 | if(nums1[i] <= nums2[j]){ 11 | nums1[k] = nums2[j]; 12 | j = j - 1; 13 | k = k - 1; 14 | }else{ 15 | nums1[k] = nums1[i]; 16 | i = i - 1; 17 | k = k - 1; 18 | } 19 | }else{ 20 | if(j>=0){ 21 | nums1[k] = nums2[j]; 22 | j = j - 1; 23 | k = k - 1; 24 | }else if (i>=0){ 25 | nums1[k] = nums1[i]; 26 | i = i - 1; 27 | k = k - 1; 28 | } 29 | } 30 | } 31 | }; 32 | 33 | /** 34 | * 35 | AI Advice: 36 | 37 | Your implementation of the merge function in TypeScript looks good overall! Here are some observations and suggestions for improvement: 38 | 39 | Strengths: 40 | Two-Pointer Approach: You've correctly implemented the two-pointer technique, which is efficient for merging sorted arrays. 41 | In-Place Modification: The function adheres to the requirement of modifying nums1 in-place. 42 | Suggestions for Improvement: 43 | Simplify Conditions: The outer while(k >= 0) loop is good, but you could simplify the conditions inside by first checking if either pointer has reached the start of its respective array. This could make the logic a bit clearer. 44 | 45 | Reduce Redundancy: The checks for i >= 0 and j >= 0 can be combined. Instead of nesting conditions, you can check for remaining elements in a single block after the primary logic. 46 | 47 | Code Readability: Adding comments or more descriptive variable names can enhance readability. For instance, you could name k something like mergeIndex for clarity. 48 | */ -------------------------------------------------------------------------------- /2024/88. Merge Sorted Array/photos/01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/88. Merge Sorted Array/photos/01.jpg -------------------------------------------------------------------------------- /2024/88. Merge Sorted Array/photos/02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hooooooouzx/leetcodeLog/fd57163918a4ce7961f99e3e4926000da2f6fac3/2024/88. Merge Sorted Array/photos/02.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # leetcodeLog 2 | Ethan daily algorithm practice --------------------------------------------------------------------------------