问题描述
如果元素
x
在长度为m
的整数数组arr
中满足freq(x) * 2 > m
,那么我们称x
是 支配元素 。其中freq(x)
是x
在数组arr
中出现的次数。注意,根据这个定义,数组arr
最多 只会有 一个 支配元素。给你一个下标从 0 开始长度为
n
的整数数组nums
,数据保证它含有一个支配元素。你需要在下标
i
处将nums
分割成两个数组nums[0, ..., i]
和nums[i + 1, ..., n - 1]
,如果一个分割满足以下条件,我们称它是 合法 的:
0 <= i < n - 1
nums[0, ..., i]
和nums[i + 1, ..., n - 1]
的支配元素相同。这里,
nums[i, ..., j]
表示nums
的一个子数组,它开始于下标i
,结束于下标j
,两个端点都包含在子数组内。特别地,如果j < i
,那么nums[i, ..., j]
表示一个空数组。请你返回一个 合法分割 的 最小 下标。如果合法分割不存在,返回
-1
。
示例
示例 1:
输入:nums = [1,2,2,2] 输出:2 解释:我们将数组在下标 2 处分割,得到 [1,2,2] 和 [2] 。 数组 [1,2,2] 中,元素 2 是支配元素,因为它在数组中出现了 2 次,且 2 * 2 > 3 。 数组 [2] 中,元素 2 是支配元素,因为它在数组中出现了 1 次,且 1 * 2 > 1 。 两个数组 [1,2,2] 和 [2] 都有与 nums 一样的支配元素,所以这是一个合法分割。 下标 2 是合法分割中的最小下标。示例 2:
输入:nums = [2,1,3,1,1,1,7,1,2,1] 输出:4 解释:我们将数组在下标 4 处分割,得到 [2,1,3,1,1] 和 [1,7,1,2,1] 。 数组 [2,1,3,1,1] 中,元素 1 是支配元素,因为它在数组中出现了 3 次,且 3 * 2 > 5 。 数组 [1,7,1,2,1] 中,元素 1 是支配元素,因为它在数组中出现了 3 次,且 3 * 2 > 5 。 两个数组 [2,1,3,1,1] 和 [1,7,1,2,1] 都有与 nums 一样的支配元素,所以这是一个合法分割。 下标 4 是所有合法分割中的最小下标。示例 3:
输入:nums = [3,3,3,3,7,2,2] 输出:-1 解释:没有合法分割。提示:
1 <= nums.length <= 105
1 <= nums[i] <= 109
nums
有且只有一个支配元素。
问题分析:
今天又是阳光明媚,适合CV的一天呢。从问题描述中我们可以得到的最关键信息,就是支配元素仅有一个,因此我们不难想出,只有众数能满足这个要求。因此我们先遍历数组得到众数的值。并统计众数的个数,for循环遍历数组找到分割点即可,如果找不到就返回-1。
代码如下:
class Solution {
public:
int minimumIndex(vector<int>& nums) {
int mode = 0, cnt = 0, n = nums.size();
//找众数mode
for(auto & i : nums)
{
if(!cnt)
mode = i;
if(mode == i)
cnt ++;
else
cnt --;
}
//统计mode的个数
int pre = 0, post = 0;
for(auto &i : nums)
{
if(i == mode)
post ++;
}
for(int i = 0; i < n - 1; i ++)
{
//每次遇到mode就把pre+1,相对的post-1
if(nums[i] == mode)
{
pre ++;
post --;
}
//判断该分割点是否满足题意,满足就返回分割点
if(pre * 2 > i + 1 && post * 2 > n - i - 1)
return i;
}
return -1;
}
};