题目七:
给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一。
注意事项
数组中只有唯一的主元素。
样例
给出数组[1,2,1,2,1,3,3] 返回 1
代码:
class Solution {
public:
/*
* @param nums: a list of integers
* @return: The majority number that occurs more than 1/3
*/
int majorityNumber(vector<int> &nums) {
// write your code here
int size = nums.size()/3;
int i;
int cnt = 0;
int result = 0;
int num1,num2,num3;
int time1 = 0,time2 = 0,time3 = 0;
num1 = Get(nums,0,size-1);
num2 = Get(nums,size,2*size-1);
num3 = Get(nums,2*size,nums.size()-1);
if(num1 == num2&&num1 == num3&&num2 == num3)
{
return num1;
}
else if(num1 != num2||num1 != num3||num2 != num3)
{
for(i = 0;i<nums.size();i++)
{
if(nums[i] == num1)
{
time1++;
}
else if(nums[i] == num2)
{
time2++;
}
else if(nums[i] == num3)
{
time3++;
}
}
if(time1>size)
{
return num1;
}
else if(time2>size)
{
return num2;
}
else if(time3>size)
{
return num3;
}
else//不是num1,num2,num3
{
for(i = 0;i<=nums.size()-1;i++)
{
if(nums[i]!=num1&&nums[i]!=num2&&nums[i]!=num3)
{
if(cnt == 0)
{
result = nums[i];
cnt++;
}
else
{
if(result!=nums[i])
{
cnt--;
}
else
{
cnt++;
}
}
}
}
return result;
}
}
}
int Get(vector<int> &nums,int start,int end)
{
int cnt = 0;
int result = 0;
int i;
for(i = start;i<=end;i++)
{
if(cnt == 0)
{
result = nums[i];
cnt++;
}
else
{
if(result!=nums[i])
{
cnt--;
}
else
{
cnt++;
}
}
}
return result;
}
};
嘿嘿嘿,题目和昨天的类似,不过这次是要求出现次数严格大于元素个数的1/3。然后题目的标签有贪心算法,然后我就百度了一下贪心算法,/*****/中内容来源于百度百科
/*思想
贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止[3] 。
过程
建立数学模型来描述问题;
把求解的问题分成若干个子问题;
对每一子问题求解,得到子问题的局部最优解;
把子问题的解局部最优解合成原来解问题的一个解。*/
我是这样想的,把整个数组分成3子数组(size = nums.size()/3):【0,size-1】【size,2*size-1】【2*size,nums.size()-1】。比如数组元素有8个,分别分成2,2,4组,为什么不分成3,3,2呢?看题目给的样例,七个元素,分别是
[1,2,1,2,1,3,3],1有三个,7/3=2,3>2,所以主元素是1,由此可以看出,所谓1/3的标准就是按着程序中size = nums.size()/3的结果规定的。(此后仍然是8个元素为例)8/3=2,所以分组分成2,2,4三组。那么主元素出现有以下几种可能
(1)、三组中都有主元素而且主元素个数在自己的子数组中不占优,这种不占优的情况只有在size=2(数组元素个数是6,7,8)的时候才出现,原因是,size是2,那么主元素个数至少要有三个,因为把数组分成三个子数组,所以每个数组中恰好有一个的时候,代码中返回的num1,num2,num3都不一定是主元素,相对的time1,time2,time3就不一定是大于size的,就像【2,1】【3,1】【1,5,6,9】,返回的num1,num2,num3分别是2,3,6,很显然主元素是1,那么对于这种很特殊的情况,majorityNumber函数中else对应的情况就是专门处理这种情况的,在刨去已经被排除的num1,num2,num3的数组中,主元素一定是占优势的,所以用我昨天的博客中的第二种方法稍作改进就可以找到主元素了。传送门
点击打开链接
(2)、当size=1或者是size>=3的时候,主元素至少在一个子数组内是占优势的。size=1(数组元素个数是3,4,5)的时候,至少有两个子数组的元素个数是1,假如主元素在这两个子数组中的一个内或者是同时存在于两个中,很明显是占优势的,如果刚好全部在元素个数大于1的子数组内,也就是说在这个子数组中至少有两个主元素存在,而这个子数组中的元素数只有2,3(数组元素是4,5时)两种情况,所以肯定是占优势的。size>=3时,主元素个数>=4,主元素至少在一个子数组中占优势,也就是说返回的num1,num2,num3中至少一个是主元素,经过后续的遍历确定time1,time2,time3后就能确定哪个是主元素了。
不过总有种想的太麻烦的感觉,如果哪位大佬有更好的改进方法,欢迎交流。