前言:本期是关于多数元素的详解,内容包括四大模块:题目,代码实现,大致思路,代码解读
今天你c了吗?
题目:
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:nums = [3,2,3]
输出:3
示例 2:
输入:nums = [2,2,1,1,1,2,2]
输出:2
代码实现:
int majorityElement(int* nums, int numsSize)
{
int i = 0;
int count = 1;
int vast_num = nums[0];
for (i = 1; i < numsSize; i++)
{
if (nums[i] == vast_num)
{
count++;
}
else
{
count--;
if (count == 0)
{
vast_num = nums[i + 1];
}
}
}
return vast_num;
}
大致思路:
预备了解:
count:统计多数元素的个数
vast_num:多数元素
1. 多数元素是数组中出现次数 大于 ⌊ n/2 ⌋
的元素,即多数元素的个数等于n/2的那一部分可以匹敌其他数字的个数和,故而我们可以采用互拼思想
2. 互拼思想:消耗战术
a. 把这些所有的数字看成士兵,分属两个阵容,一个阵容全部由这个多数元素组成,一个阵容由全部的非多数元素组成
b. 设定数组中的第一个元素为多数元素,去和剩下的数字比较
若是值相同,则多数元素阵容里的士兵成员+1
若是值不同,则多数元素阵容里的士兵成员-1(两个不同阵容的士兵同归于尽)
若是当前的多数元素里的士兵们全部被消耗完了,则更换另一个数字为多数元素
只要是真正的多数元素,此阵容里的士兵是不会被其他的数字联合起来组成的士兵消耗殆尽的
最终留下来的数字就是多数元素
代码解读:
part 1:设定多数元素
int count = 1;
int vast_num = nums[0];
设定数组中的第一个元素就是多数元素,则多数元素阵容里的士兵成员的个数变成1
part 2:互拼消耗
for (i = 1; i < numsSize; i++)
{
if (nums[i] == vast_num)
{
count++;
}
else
{
count--;
if (count == 0)
{
vast_num = nums[i + 1];
}
}
}
从第二个元素开始进行比较:
若是当前下标为i的元素和当前的多数元素不同,则二者归属不同阵容,士兵互拼消耗,多数元素阵容里的士兵个数-1
多数元素阵容里的士兵每-1,就需要判断当前的多数元素阵容里的士兵个数是否为0
若是变成0,则说明当前的多数元素不是真正的多数元素,更换下标为i+1的元素作为新的多数元素
(因为下标为i的元素已经和旧的多数元素阵容里的一个士兵同归于尽了)
若是值相同,则二者归属相同阵容,多数元素阵容里的士兵个数+1
part 3
最终两个阵容的互拼消耗的结果是:只会留下真正多数元素阵容里的士兵