基于分治法的JPEG图像数组多数元素判定问题
Great question! Let's break down how to solve this using divide and conquer, which fits the O(n log n) time requirement perfectly. First, let's make sure we're clear on the problem constraints: we can only check if two elements are equal (no ordering comparisons), and we need to determine if there's an element that appears more than half the time in the array.
Key Insight for Divide and Conquer
The critical observation here is: If an element is the majority element of the entire array, it must be the majority element of at least one of the two halves of the array.
Why? Let's prove it quickly: Suppose element x is the majority of the full array (appears > n/2 times). If x were NOT the majority of either half, then it would appear ≤ len(left)/2 times in the left half and ≤ len(right)/2 times in the right half. Adding those gives ≤ (len(left)+len(right))/2 = n/2 times, which contradicts x being a majority. So this holds.
Step-by-Step Algorithm
We'll split the problem into three parts: divide, conquer, and combine.
1. Divide
Split the array into two roughly equal halves (left and right).
2. Conquer
Recursively check if each half has a potential majority candidate. For base cases:
- If the subarray has only one element, that element is the candidate.
- For larger subarrays, recursively get candidates from both halves.
3. Combine
Once we have candidates from both halves, we need to verify if either candidate is actually the majority element of the full array:
- Count the occurrences of each candidate in the entire array.
- If either count exceeds n/2, return
True(there is a majority element). - If neither does, return
False.
Pseudocode Implementation
Here's a clear pseudocode breakdown of the approach:
# Main function to check for majority element def has_majority_element(arr): n = len(arr) if n == 0: return False if n == 1: return True mid = n // 2 left_candidate = find_candidate(arr[:mid]) right_candidate = find_candidate(arr[mid:]) # Check if left candidate is majority in full array if count_occurrences(arr, left_candidate) > n / 2: return True # Check if right candidate is majority in full array if count_occurrences(arr, right_candidate) > n / 2: return True # Neither candidate is a majority return False # Helper to find a potential majority candidate in a subarray def find_candidate(subarr): m = len(subarr) if m == 1: return subarr[0] mid = m // 2 left_cand = find_candidate(subarr[:mid]) right_cand = find_candidate(subarr[mid:]) # If both halves have the same candidate, it's the one if left_cand == right_cand: return left_cand # Otherwise, return the candidate with more occurrences in the subarray count_left = count_occurrences(subarr, left_cand) count_right = count_occurrences(subarr, right_cand) return left_cand if count_left > count_right else right_cand # Helper to count occurrences of an element in an array def count_occurrences(arr, elem): count = 0 for x in arr: if x == elem: count += 1 return count
Time Complexity Analysis
Let's break down the time cost:
- The
count_occurrencesfunction runs in O(n) time. - The
find_candidatefunction follows the recurrence relation:T(n) = 2*T(n/2) + O(n). By the Master Theorem, this resolves to O(n log n). - The main function calls
find_candidatetwice (O(n log n) total) andcount_occurrencestwice (O(n) total). So overall time complexity is O(n log n), which meets the problem's requirement.
Example Walkthrough
Let's take an example array [2, 2, 1, 1, 2]:
- Split into left
[2,2]and right[1,1,2]. - Left candidate is
2(since it's the majority of the left half). - Right candidate: split
[1,1,2]into[1]and[1,2]. The candidate for[1,2]is either1or2(counts are equal, so we can return either). Let's say we return1. Then compare1(from left of right half) and1(from right of right half) → right candidate is1. - Count
2in full array: 3 times, which is > 5/2 = 2.5. So we returnTrue.
This works exactly as intended!
内容的提问来源于stack exchange,提问作者Kushagra Chatterjee

