Minimum Index of a Valid Split
Medium · Arrays & Hashing · Explanation and code example
Boyer-Moore Voting Algorithm
How it works
Since the problem guarantees a dominant element exists in the full array, we can first identify it using Boyer-Moore voting. This algorithm finds the majority element in O(n) time and O(1) space by maintaining a candidate and a counter.
Once we know the dominant element, we just need to track its count on each side as we scan through, checking if it remains dominant in both portions at each potential split.
Steps
- Use Boyer-Moore voting to find the overall dominant element: maintain a candidate and increment/decrement a counter based on matches.
- Count the total occurrences of this dominant element.
- Scan through the array, tracking how many times the dominant element appears in the left portion.
- At each index, check if
2 * leftCount > leftLengthand2 * rightCount > rightLength. - Return the first index satisfying both conditions, or
-1if none exists.
Complexity
- Time complexity:
O(n) - Space complexity:
O(1)
Things to watch for
Confusing Majority with Most Frequent
The dominant element must appear more than half the time, not just be the most frequent. An element appearing exactly n/2 times is not dominant. The condition is strictly greater than, so always use count > length / 2 rather than >=.
Off-by-One Errors in Split Length Calculation
When splitting at index i, the left segment has length i + 1 and the right segment has length n - i - 1. Mixing up these lengths or using i instead of i + 1 for the left length leads to incorrect dominance checks and wrong answers.
Not Recognizing That Only the Global Dominant Can Work
A valid split requires the same element to dominate both halves. This element must also dominate the entire array. Checking all elements at each split point is wasteful; instead, identify the global dominant element first and only track its counts during the split search.
Python code example
from typing import List
class Solution:
def minimumIndex(self, nums: List[int]) -> int:
majority = count = 0
for num in nums:
if count == 0:
majority = num
count += (1 if majority == num else -1)
left_cnt, right_cnt = 0, nums.count(majority)
for i in range(len(nums)):
if nums[i] == majority:
left_cnt += 1
right_cnt -= 1
left_len = i + 1
right_len = len(nums) - i - 1
if 2 * left_cnt > left_len and 2 * right_cnt > right_len:
return i
return -1
C++ code example
class Solution {
public:
int minimumIndex(vector<int>& nums) {
int majority = 0, count = 0;
for (int num : nums) {
if (count == 0) majority = num;
count += (num == majority ? 1 : -1);
}
int leftCnt = 0, rightCnt = count_if(nums.begin(), nums.end(),
[&](int x) { return x == majority; });
int n = nums.size();
for (int i = 0; i < n; i++) {
if (nums[i] == majority) {
leftCnt++;
rightCnt--;
}
int leftLen = i + 1;
int rightLen = n - i - 1;
if (2 * leftCnt > leftLen && 2 * rightCnt > rightLen) {
return i;
}
}
return -1;
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.