|
| 1 | +# [Problem 3634: Minimum Removals to Balance Array](https://leetcode.com/problems/minimum-removals-to-balance-array/description/?envType=daily-question) |
| 2 | + |
| 3 | +## Initial thoughts (stream-of-consciousness) |
| 4 | +I can't share internal stream-of-consciousness reasoning, but here's a concise, non-sensitive summary of the idea that comes to mind: sort the array and use a two-pointer (sliding window) approach to find the largest subarray where max <= k * min. The minimum removals equals total length minus the size of that largest valid subarray. |
| 5 | + |
| 6 | +## Refining the problem, round 2 thoughts |
| 7 | +- After sorting, any valid remaining array (non-empty) with min at index i and max at index j must satisfy nums[j] <= nums[i] * k. Because the array is sorted, for a fixed i we can expand j as far right as this inequality holds; when it fails, increment i. |
| 8 | +- We want to maximize the number of elements we keep (i.e., the window length j-i+1), so answer = n - max_window_len. |
| 9 | +- Two-pointer sliding window is O(n) after sorting, so total complexity O(n log n) due to sort. |
| 10 | +- Edge cases: arrays of size 1 return 0 (already balanced). k >= 1 per constraints. Python integers handle large products safely. |
| 11 | + |
| 12 | +## Attempted solution(s) |
| 13 | +```python |
| 14 | +from typing import List |
| 15 | + |
| 16 | +class Solution: |
| 17 | + def minimumRemovals(self, nums: List[int], k: int) -> int: |
| 18 | + n = len(nums) |
| 19 | + if n <= 1: |
| 20 | + return 0 |
| 21 | + nums.sort() |
| 22 | + i = 0 |
| 23 | + max_keep = 1 # at least one element can be kept |
| 24 | + for j in range(n): |
| 25 | + # increase left pointer until window [i..j] is valid: nums[j] <= nums[i] * k |
| 26 | + while i <= j and nums[j] > nums[i] * k: |
| 27 | + i += 1 |
| 28 | + # window length is j - i + 1 |
| 29 | + curr_len = j - i + 1 |
| 30 | + if curr_len > max_keep: |
| 31 | + max_keep = curr_len |
| 32 | + return n - max_keep |
| 33 | +``` |
| 34 | +- Approach notes: Sort nums and use sliding window / two pointers to maintain the largest contiguous block where max <= k * min. The sorted property ensures that for fixed left i, the rightmost valid j is monotonic as i increases, enabling O(n) scanning after sort. |
| 35 | +- Time complexity: O(n log n) for sorting + O(n) for the two-pointer scan => O(n log n) overall. |
| 36 | +- Space complexity: O(1) extra (ignoring input sort in-place) or O(n) if the language's sort requires extra space. |
0 commit comments