169. Majority Element

问题:

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

我的解法:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        sort(nums.begin(),nums.end());
       return nums[(nums.size()-1)/2];
    }
};

解释:
就是排好序后,找中间的那个数。因为假如是大多数的话,那么肯定中间那个数就是跟大多数数字一样的数。但是或许我们不需要整个排序。所以我·查了一下别人的做法。

我发现有一种moore voting alogorothm的做法很好。主要的思想是,找出一对对不相等的数对来,并删除,最后剩下的数就是占大多数的数。具体实现时,就是用一个计数值,当后面扫描到的数与主数相同时,计数值加一,与主数不同时,减一。当计数值为零时,变换主数。最后输出主数。

这是代码实现:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
    if(nums.size() <=0)return NULL;
    int cnt = 1,tmp = nums[0];
    for(int i=1;i<nums.size();i++){
        if(0 == cnt)
             tmp = nums[i];
        if(nums[i]==tmp)
             cnt++;
        else cnt--;
    }
    return tmp;
    }
};

注意到 if(nums[i]==tmp)
cnt++;
这条语句是使用==,然后cnt++,而不是!= 然后–。
这是因为前面使用了tmp=nums[i]赋值,在很多情况下都是==的情况,所以这样写会快。虽然效果都相同,但是这个细节可以提速。

后来发现,也可以使用哈希表来做
先来介绍一下unordered_map。
我自己理解的就是建立一种一一对应的映射关系,如把学生的学号和名字联系在一起,输入学号即可快速检索到名字。又如月份名和天数:months[“august”] = 31;
cout << “august-> ” << months[“august”] << std::endl;
输出的是31;
即通过august检索到31.

下面是官方库的介绍:

哈希map是一种关联容器,通过键值和映射值存储元素。允许根据键值快速检索各个元素。
在unordered_map中,键值一般用来唯一标识元素,而对应的值是一个对象关联到这个键的内容。键映射值的类型可能会有所不同。
在内部unordered_map的元素不以键值或映射的元素作任何特定的顺序排序,其存储位置取决于哈希值允许直接通过其键值为快速访问单个元素(具有恒定平均的平均时间复杂度)。
unordered_map容器比map容器更快地通过键值访问他们的单个元素,虽然unordered_map一般都是比map通过其元素的一个子集范围迭代效率低。
哈希map允许使用操作运算符(运算符[])以其键值作为参数直接访问元素。
容器属性
关联
在关联容器的元素通过键值引用,而不是由他们在容器中的绝对位置。
无序
无序容器通过哈希表组织其元素的使用,允许通过键值快速访问其对应元素。

映射
每个元素关联到一键值对应一映射值:键值用于识别元素,其主要内容是键对应的值。

唯一键
在容器中没有两个元素可以有相同的键。

分配器的唤醒
容器使用一个分配器对象动态地处理其存储需求。
Template parameters
Key
Type of the key values. Each element in an unordered_map is uniquely identified by its key value.
Aliased as member type unordered_map::key_type.
T
Type of the mapped value. Each element in an unordered_map is used to store some data as its mapped value.
Aliased as member type unordered_map::mapped_type. Note that this is not the same as unordered_map::value_type (see below).
Hash
A unary function object type that takes an object of type key type as argument and returns a unique value of type size_t based on it. This can either be a class implementing a function call operator or a pointer to a function (see constructor for an example). This defaults to hash, which returns a hash value with a probability of collision approaching 1.0/std::numeric_limits::max().
The unordered_map object uses the hash values returned by this function to organize its elements internally, speeding up the process of locating individual elements.
Aliased as member type unordered_map::hasher.
Pred
A binary predicate that takes two arguments of the key type and returns a bool. The expression pred(a,b), where pred is an object of this type and a and b are key values, shall return true if a is to be considered equivalent to b. This can either be a class implementing a function call operator or a pointer to a function (see constructor for an example). This defaults to equal_to, which returns the same as applying the equal-to operator (a==b).
The unordered_map object uses this expression to determine whether two element keys are equivalent. No two elements in an unordered_map container can have keys that yield true using this predicate.
Aliased as member type unordered_map::key_equal.
Alloc
Type of the allocator object used to define the storage allocation model. By default, the allocator class template is used, which defines the simplest memory allocation model and is value-independent.
Aliased as member type unordered_map::allocator_type.

In the reference for the unordered_map member functions, these same names (Key, T, Hash, Pred and Alloc) are assumed for the template parameters.
说了那么多,下面是使用哈希表的代码实现:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        unordered_map<int, int> counts; 
        int n = nums.size();
        for (int i = 0; i < n; i++)
            if (++counts[nums[i]] > n / 2)
                return nums[i];
          return 0;
    }
};

你可能感兴趣的:(169. Majority Element)