2017算法课.02(majority element)

来源:互联网 发布:淘宝旺旺卖家 编辑:程序博客网 时间:2024/05/13 07:52

这道题目,前提条件已经说明了,nums数组必然存在这么一个数,他的元素个数要大于数组中所有元素数目的一半。所以,这里就不必考虑是否不存在的情况。


例如:

假定一组数是 2 3  6  2 3 2 2

此时2的数目4个,大于整个数组所有元素数目7个。所以输出的结果应该是2.


最简单的方法当然就是暴力解法:

先访问一遍所有的元素,并将元素储存在新的对象数组里面。创建一个结构体,两个部分组成。一个是数字num,另一个是该数字出现的次数count,并初始化为0.在访问的过程中,遇到相同的元素,则将对应的次数+1.然后,直至最后,count最大的元素输出即可。这个方法,理解起来很简单。

对应此题目的解法就是:

创建临时数组temp[10],创建结构体struct  struc{int num;int count; a(){count = 0; num = 0;}} 然后访问数组[2,3,6,2,3,2,2]的每一个元素,访问2,将结构体1{2;1}放入temp【0】中去,然后 访问3,将结构体2{3,1}放到temp【1】中去。。。。。。。。。当遇到重复的数字,只需将该数字的count++就行。最后比较count大小,大的那个输出即可。

上述方法是最先想到的方法,但是其代码繁琐,易出错。理论上可以解决。由于学习了分治算法,采用分治算法的思想,或许更简单,于是,尝试运用分治算法!





分治算法:首先将序列均分成两半,分别找出每一半的主元素。如果两个主元素相等,则直接返回1个;否则遍历完整序列,返回出现次数多于一半的那个主元素。
边界条件:序列只有一个元素时,直接返回该元素。


话不多说,先上代码:

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;


int recursive(vector<int>& nums, int l, int r){
 if(l == r){
  return  nums[l];
 }
 
 int mid = (l + r) / 2;                  //................................................................中分
 int leftnum = recursive(nums, l , mid);//.................................................... 找到左半部分的主元素
 int rightnum = recursive(nums, mid + 1, r);//............................................ 找到右半部分的主元素
 int c1 = count(nums.begin() + l,nums.begin() + r + 1, leftnum);//............. 左半部分主元素的出现次数
 int c2 = count(nums.begin() + l,nums.begin() + r + 1, rightnum);//...........右半部分主元素的出现次数
 if(c1 > c2 ){//..............................................................................................如果左大于右,则,左边的主元素是总的主元素
  return leftnum;
 }
 else return rightnum;
}

int majorityElement(vector<int>& nums) {
  return recursive(nums, 0 , nums.size() - 1);
}



1 0
原创粉丝点击