技术问询:如何找到包含n个数值中半数的最小区间?
Great question! Let's walk through how to solve this problem clearly, with actionable steps and code examples.
First, let's clarify the problem definition to avoid ambiguity: Given a list of n numerical values, we need to find the shortest possible interval [a, b] such that this interval contains at least half of the elements (specifically, ⌈n/2⌉ elements—for even n, that's n/2; for odd n, that's (n+1)/2).
Core Approach
The key insight here is that sorted data makes this problem trivial to solve with a sliding window (two-pointer) technique. Here's why:
- In an unsorted array, elements that satisfy the "half count" condition might be scattered, leading to larger intervals. Sorting groups similar values together, so the smallest valid interval will always correspond to a consecutive subarray in the sorted list.
Step-by-Step Solution
Sort the Input Array
Start by sorting the list of values. This allows us to use a sliding window to efficiently find the minimal interval.Initialize Sliding Window
- Set a left pointer at the start of the sorted array.
- Iterate through the array with a right pointer, expanding the window until it contains at least
⌈n/2⌉elements.
Shrink the Window to Find the Minimum Length
Once the window meets the element count requirement, calculate its length (arr[right] - arr[left]). If this is shorter than the current minimum, update your result interval. Then, move the left pointer forward to try shrinking the window while still meeting the count requirement—this helps us find the smallest possible interval for each right pointer position.Return the Minimal Interval
After processing all elements, the smallest interval you tracked will be your answer.
Example Walkthrough
Let's take an example to see this in action:
- Input array:
[1, 7, 2, 10, 4, 8](n=6, so we need at least 3 elements) - Sorted array:
[1, 2, 4, 7, 8, 10] - Sliding window steps:
- Right pointer reaches index 2 (value 4): window
[1,2,4](3 elements), length 3. This is our first candidate. - Right pointer moves to 3 (7): window
[1,2,4,7]—we can shrink left to index 1, window[2,4,7](length 5, larger than 3, so no update). - Right pointer moves to 4 (8): window
[2,4,7,8]—shrink left to index 2, window[4,7,8](length 4, still larger than 3). - Right pointer moves to 5 (10): window
[4,7,8,10]—shrink left to index 3, window[7,8,10](length 3, same as our first candidate).
- Right pointer reaches index 2 (value 4): window
The minimal intervals here are [1,4] and [7,10], both with length 3.
Code Implementation (Python)
def find_smallest_half_interval(arr): n = len(arr) if n == 0: return [] # Sort the array to enable sliding window sorted_arr = sorted(arr) # Calculate the minimum number of elements we need to include required_elements = (n + 1) // 2 min_length = float('inf') result_interval = [] left = 0 for right in range(n): # Shrink the window as much as possible while meeting the element requirement while right - left + 1 >= required_elements: current_length = sorted_arr[right] - sorted_arr[left] # Update the minimal interval if current is shorter if current_length < min_length: min_length = current_length result_interval = [sorted_arr[left], sorted_arr[right]] # Move left pointer to try smaller windows left += 1 return result_interval # Test cases print(find_smallest_half_interval([1,3,5,7,9])) # Output: [1,5] print(find_smallest_half_interval([1,2,4,7,8,10])) # Output: [1,4] print(find_smallest_half_interval([5])) # Output: [5,5]
Time Complexity
- Sorting takes
O(n log n)time. - The sliding window traversal is
O(n)since each element is processed exactly twice (once by the right pointer, once by the left pointer). - Overall time complexity:
O(n log n), which is efficient for most practical use cases.
内容的提问来源于stack exchange,提问作者Alex Giucăl

