-
Notifications
You must be signed in to change notification settings - Fork 0
Add explanation and solution for LeetCode problem 2119 (Minimum Number of Operations to Make Array Continuous) #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,128 @@ | ||||||||||||||||||||||||||
| ## 2119. Minimum Number of Operations to Make Array Continuous [Hard] | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| https://leetcode.com/problems/minimum-number-of-operations-to-make-array-continuous | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Description | ||||||||||||||||||||||||||
| You are given an integer array `nums`. In one operation, you can replace **any** element in `nums` with **any** integer. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| `nums` is considered **continuous** if both of the following conditions are fulfilled: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - All elements in `nums` are **unique**. | ||||||||||||||||||||||||||
| - The difference between the **maximum** element and the **minimum** element in `nums` equals `nums.length - 1`. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| For example, `nums = [4, 2, 5, 3]` is **continuous**, but `nums = [1, 2, 3, 5, 6]` is **not continuous**. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Return *the **minimum** number of operations to make* `nums` **continuous**. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Examples** | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```tex | ||||||||||||||||||||||||||
| Example 1: | ||||||||||||||||||||||||||
| Input: nums = [4,2,5,3] | ||||||||||||||||||||||||||
| Output: 0 | ||||||||||||||||||||||||||
| Explanation: nums is already continuous. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Example 2: | ||||||||||||||||||||||||||
| Input: nums = [1,2,3,5,6] | ||||||||||||||||||||||||||
| Output: 1 | ||||||||||||||||||||||||||
| Explanation: One possible solution is to change the last element to 4. | ||||||||||||||||||||||||||
| The resulting array is [1,2,3,5,4], which is continuous. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Example 3: | ||||||||||||||||||||||||||
| Input: nums = [1,10,100,1000] | ||||||||||||||||||||||||||
| Output: 3 | ||||||||||||||||||||||||||
| Explanation: One possible solution is to: | ||||||||||||||||||||||||||
| - Change the second element to 2. | ||||||||||||||||||||||||||
| - Change the third element to 3. | ||||||||||||||||||||||||||
| - Change the fourth element to 4. | ||||||||||||||||||||||||||
| The resulting array is [1,2,3,4], which is continuous. | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Constraints** | ||||||||||||||||||||||||||
| ```tex | ||||||||||||||||||||||||||
| - 1 <= nums.length <= 10^5 | ||||||||||||||||||||||||||
| - 1 <= nums[i] <= 10^9 | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Explanation | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Strategy | ||||||||||||||||||||||||||
| Let's restate the problem: You're given an array, and you need to find the minimum number of operations to make it continuous. A continuous array has unique elements where the difference between max and min equals the length minus 1. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| This is a **sliding window problem** that requires understanding what makes an array continuous and finding the optimal window of elements to keep. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **What is given?** An array of integers that can be very large (up to 100,000 elements). | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **What is being asked?** Find the minimum operations to make the array continuous. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Constraints:** The array can be up to 100,000 elements long, with values up to 10⁹. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Edge cases:** | ||||||||||||||||||||||||||
| - Single element array | ||||||||||||||||||||||||||
| - Already continuous array | ||||||||||||||||||||||||||
| - Array with all identical values | ||||||||||||||||||||||||||
| - Very large gaps between elements | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **High-level approach:** | ||||||||||||||||||||||||||
| The solution involves sorting the array and using a sliding window approach to find the optimal subset of elements that can form a continuous array with minimal operations. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Decomposition:** | ||||||||||||||||||||||||||
| 1. **Sort the array**: This helps us identify potential continuous subsequences | ||||||||||||||||||||||||||
| 2. **Use sliding window**: Find the longest window that can be made continuous | ||||||||||||||||||||||||||
| 3. **Calculate operations**: Determine how many elements need to be changed | ||||||||||||||||||||||||||
| 4. **Find minimum**: Try different window sizes to find the optimal solution | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Brute force vs. optimized strategy:** | ||||||||||||||||||||||||||
| - **Brute force**: Try all possible subsets. This is extremely inefficient. | ||||||||||||||||||||||||||
| - **Optimized**: Use sliding window with binary search. This takes O(n log n) time. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Steps | ||||||||||||||||||||||||||
| Let's walk through the solution step by step using the second example: `nums = [1,2,3,5,6]` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Step 1: Sort the array** | ||||||||||||||||||||||||||
| - Original: [1,2,3,5,6] | ||||||||||||||||||||||||||
| - Sorted: [1,2,3,5,6] (already sorted) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Step 2: Understand what makes an array continuous** | ||||||||||||||||||||||||||
| - For length 5, we need: max - min = 5 - 1 = 4 | ||||||||||||||||||||||||||
| - So we need elements that span exactly 4 values | ||||||||||||||||||||||||||
| - Example: [1,2,3,4,5] has max=5, min=1, difference=4 ✓ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Step 3: Use sliding window approach** | ||||||||||||||||||||||||||
| - Start with window size = array length | ||||||||||||||||||||||||||
| - Try to find a window that can be made continuous | ||||||||||||||||||||||||||
| - For each window, calculate how many operations are needed | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Step 4: Calculate operations for different windows** | ||||||||||||||||||||||||||
|
Comment on lines
+91
to
+96
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Clarify the algorithm and fix MD036 Describe the two-pointer window on unique values; convert bold to headings. -**Step 3: Use sliding window approach**
-- Start with window size = array length
-- Try to find a window that can be made continuous
-- For each window, calculate how many operations are needed
+#### Step 3: Two-pointer sliding window on unique values
+- Let n = nums.length. After sorting and deduping to `unique`, keep pointers i and j.
+- While j < len(unique) and unique[j] <= unique[i] + n - 1, advance j.
+- Keep = j - i (values we can keep); ops = n - Keep. Then increment i; j never moves backward.
@@
-**Step 4: Calculate operations for different windows**
+#### Step 4: Calculate operations for different windows📝 Committable suggestion
Suggested change
🧰 Tools🪛 LanguageTool[grammar] ~91-~91: There might be a mistake here. (QB_NEW_EN) [grammar] ~92-~92: There might be a mistake here. (QB_NEW_EN) 🪛 markdownlint-cli2 (0.17.2)91-91: Emphasis used instead of a heading (MD036, no-emphasis-as-heading) 96-96: Emphasis used instead of a heading (MD036, no-emphasis-as-heading) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| - **Window [1,2,3,5,6]**: | ||||||||||||||||||||||||||
| - Current span: 6 - 1 = 5 | ||||||||||||||||||||||||||
| - Need span: 5 - 1 = 4 | ||||||||||||||||||||||||||
| - Gap: 5 - 4 = 1 | ||||||||||||||||||||||||||
| - Operations needed: 1 (change 6 to 4) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - **Window [1,2,3,5]**: | ||||||||||||||||||||||||||
| - Current span: 5 - 1 = 4 | ||||||||||||||||||||||||||
| - Need span: 4 - 1 = 3 | ||||||||||||||||||||||||||
| - Gap: 4 - 3 = 1 | ||||||||||||||||||||||||||
| - Operations needed: 1 (change 5 to 3) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - **Window [2,3,5,6]**: | ||||||||||||||||||||||||||
| - Current span: 6 - 2 = 4 | ||||||||||||||||||||||||||
| - Need span: 4 - 1 = 3 | ||||||||||||||||||||||||||
| - Gap: 4 - 3 = 1 | ||||||||||||||||||||||||||
| - Operations needed: 1 (change 6 to 4) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Step 5: Find optimal solution** | ||||||||||||||||||||||||||
| - Minimum operations: 1 | ||||||||||||||||||||||||||
| - Optimal window: [1,2,3,5] → change 5 to 4 → [1,2,3,4] | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Why this works:** | ||||||||||||||||||||||||||
| The sliding window approach works because: | ||||||||||||||||||||||||||
| 1. **Optimal substructure**: The best solution for a larger array must include the best solution for a smaller subarray | ||||||||||||||||||||||||||
| 2. **Monotonicity**: If a window of size k can be made continuous, then a window of size k-1 can also be made continuous | ||||||||||||||||||||||||||
| 3. **Efficiency**: We only need to check O(n) different window sizes instead of all possible subsets | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| > **Note:** The key insight is that we can use a sliding window to find the longest subsequence that can be made continuous, and then calculate the minimum operations needed. This avoids the need to try all possible combinations. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| **Time Complexity:** O(n log n) - sorting takes O(n log n), sliding window takes O(n) | ||||||||||||||||||||||||||
| **Space Complexity:** O(1) - we only need a few variables for the sliding window | ||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,50 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def minOperations(nums): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Find the minimum number of operations to make the array continuous. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Args: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nums: List[int] - Array of integers | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Returns: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int - Minimum number of operations needed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Handle edge case | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(nums) <= 1: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Sort the array to work with ordered elements | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nums.sort() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Remove duplicates to work with unique elements | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unique_nums = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (code-quality): Convert for loop into list comprehension ( |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for i, num in enumerate(nums): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if i == 0 or num != nums[i-1]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unique_nums.append(num) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| n = len(unique_nums) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| min_operations = float('inf') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Try different window sizes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for i in range(n): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # For each starting position, find the longest window that can be made continuous | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| left = unique_nums[i] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Binary search for the rightmost element that can be part of a continuous sequence | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+29
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (performance): Binary search could replace the inner loop for efficiency. Consider using bisect_right to efficiently find the rightmost element in the window, which will improve performance for large datasets. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # starting from left | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| right = left + len(nums) - 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Find how many elements in unique_nums fall within [left, right] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # This gives us the size of the window that can be made continuous | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| count = 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for j in range(i, n): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if unique_nums[j] <= right: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| count += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Calculate operations needed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # We need to change (len(nums) - count) elements | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| operations = len(nums) - count | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| min_operations = min(min_operations, operations) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return min_operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+27
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace O(u^2) scan with true sliding window (two pointers) to meet 1e5 constraint The inner loop makes this O(u^2) in unique values and will TLE. Use two pointers so j never moves backward; overall O(u) after sort. Also removes the inaccurate “Binary search” comment. - n = len(unique_nums)
- min_operations = float('inf')
-
- # Try different window sizes
- for i in range(n):
- # For each starting position, find the longest window that can be made continuous
- left = unique_nums[i]
-
- # Binary search for the rightmost element that can be part of a continuous sequence
- # starting from left
- right = left + len(nums) - 1
-
- # Find how many elements in unique_nums fall within [left, right]
- # This gives us the size of the window that can be made continuous
- count = 0
- for j in range(i, n):
- if unique_nums[j] <= right:
- count += 1
- else:
- break
-
- # Calculate operations needed
- # We need to change (len(nums) - count) elements
- operations = len(nums) - count
- min_operations = min(min_operations, operations)
+ m = len(unique_nums)
+ min_operations = len(nums)
+ j = 0
+ for i in range(m):
+ while j < m and unique_nums[j] <= unique_nums[i] + len(nums) - 1:
+ j += 1
+ keep = j - i
+ operations = len(nums) - keep
+ if operations < min_operations:
+ min_operations = operations📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doc states sliding-window O(n log n), but code is quadratic — align code or doc
Current implementation is O(u^2). Either adopt the two-pointer change (preferred) or revise this section to note the actual complexity of the provided code.
🧰 Tools
🪛 LanguageTool
[grammar] ~66-~66: There might be a mistake here.
Context: ...tween elements High-level approach: The solution involves sorting the array ...
(QB_NEW_EN)
[grammar] ~69-~69: There might be a mistake here.
Context: ...th minimal operations. Decomposition: 1. Sort the array: This helps us identify...
(QB_NEW_EN)
🤖 Prompt for AI Agents