46. 主元素
给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一。
样例 1:
输入: [1, 1, 1, 1, 2, 2, 2] 输出: 1
样例 2:
输入: [1, 1, 1, 2, 2, 2, 2] 输出: 2
挑战
要求时间复杂度为O(n),空间复杂度为O(1)
注意事项
你可以假设数组非空,且数组中总是存在主元素。
方法一:
求中位数,主元素肯定是中位数,否则该元素数量少于n/2则不是主元素;快速排序,然后确定中位数。时间复杂度O(nlogn)
class Solution {
public:
int majorityNumber(vector<int> &nums) {
// write your code here
sort(nums.begin(),nums.end());
int len=nums.size();
return nums[len/2];
}
};
方法二:
思路比较新颖,原理是如果一个元素中存在一个主元素(个数大于n/2),则同时删除两个不相等的数,这个主元素不会改变。
简单的说就是一个大小为n的数组中存在一个元素的个数大余n/2,则如果用这个数组中其他的数和该主元素进行抵消的话,最后剩下的一定是主元素,因为主元素个数最多。
该方法可以在O(n)时间内找到主元素。十分高效。
class Solution {
public:
int majorityNumber(vector<int> &nums) {
// write your code here
if (nums.size() == 0) {
return -1;
}
int count = 0;
int major = nums[0];
//取出主元素
for (int i = 0; i < nums.size(); i++) {
if (major == nums[i]) {
count++;
} else {
count--;
}
if (count == 0) {
major = nums[i];
count++;
}
}
//判断取出的主元素是不是主元素
count = 0;
for (int i = 0; i < nums.size(); i++) {
if (major == nums[i]) {
count++;
}
}
if (count > nums.size() / 2) {
return major;
}
return -1;
}
};
47. 主元素 II
给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一。
样例
例1:
输入: [99,2,99,2,99,3,3], 输出: 99.
例2:
输入: [1, 2, 1, 2, 1, 3, 3], 输出: 1.
挑战
要求时间复杂度为O(n),空间复杂度为O(1)。
注意事项
数组中只有唯一的主元素
方法一:以空间换时间(将数组中的元素作为新建数组的下标,新建数组用于存储各元素出现的次数)
class Solution {
public:
int majorityNumber(vector<int> &nums) {
// write your code here
int i,len=nums.size(),max=nums[0];
for(i=1;i<len;i++)
{
if(max<nums[i]) max=nums[i];
}
int temp[max+1]={0};
if(len== 0)
return 0;
for(i = 0;i< len;i++){
temp[nums[i]]++;
}
for(i=0;i<max+1;i++)
{
if(temp[i]>len/3)
{
return i;
}
}
return 0;
}
};
方法二:如果出现3个不一样的数,就抵消掉。记录两个value和每个value分别的出现次数。如果遍历到的数和两个value都不等,就count都减1。最后可能会剩下两个value,再遍历一次整个数组验证一下谁是主元素。
class Solution {
public:
int majorityNumber(vector<int> &nums) {
// write your code here
int a = nums[0], cnta = 0; //我用a b分别表示两个不一样的数
int b = nums[0], cntb = 0;
int i;
for(i=0;i<nums.size();i++)
{
if(nums[i]==a)
{
cnta++;
continue;
}
if(nums[i]==b)
{
cntb++;
continue;
}
if(cnta==0)
{
a=nums[i];
cnta++;
continue;
}
if(cntb==0)
{
b=nums[i];
cntb++;
continue;
}
cnta--;
cntb--;
}
cnta = 0;
cntb = 0;
for (i=0;i<nums.size();i++)
{
if (nums[i] == a) {
cnta++;
}
else if (nums[i]== b)
{
cntb++;
}
}
if (cnta > nums.size() / 3) {
return a;
}
if (cntb > nums.size() / 3) {
return b;
}
48. 主元素 III
给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的1/k。
样例
例1:
输入: [3,1,2,3,2,3,3,4,4,4] and k=3, 输出: 3.
例2:
输入: [1,1,2] and k=3, 输出: 1.
挑战
要求时间复杂度为O(n),空间复杂度为O(k)
注意事项
数组中只有唯一的主元素
class Solution {
public:
int majorityNumber(vector<int> &nums, int k) {
// write your code here
int i,len=nums.size(),max=nums[0];
for(i=1;i<len;i++)
{
if(max<nums[i]) max=nums[i];
}
int temp[max+1]={0};
if(len== 0)
return 0;
for(i = 0;i< len;i++){
temp[nums[i]]++;
}
for(i=0;i<max+1;i++)
{
if(temp[i]>len/k)
{
return i;
}
}
return 0;
}
};