主元素II

题目七:

给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一。


注意事项

数组中只有唯一的主元素。

样例

给出数组[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后就能确定哪个是主元素了。
不过总有种想的太麻烦的感觉,如果哪位大佬有更好的改进方法,欢迎交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值