2016.5.18——leetcode:Majority Element

Majority Element

本题收获:

1.初步了解hash,nth_element的用法

2.题目的常规思路

  题目: 

  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.

  题目中已经假定了数组非空,且>n/2的值存在。题目中的隐含这个元素只有一个(一共n个数,大于n/2的肯定只有一个)。

  思路:

  我的思路:遍历数组,将数组中个数超过n/2的返回。

  leetcode/dicuss思路:这道题有很多思路,我只写下来,我认为比较易懂的思路和代码。

      1.比较取巧的思路,每次左抵消,,最后留下来的那个数就是要找的元素。

      2.hash映射,将元素和次数作为一个hash,把次数大于n/2的返回。

      3.利用nth_element,直接找到排序后位于第n/2的位置的元素。原因:如果一个数出现的次数大于n/2,那么他排序后一定位于第n/2的位置。

  代码:

  代码1:思路1代码

 1 public class Solution {
 2     public int majorityElement(int[] num) {
 3         int major=num[0], count = 1;    
 4 
 5         for(int i=1; i<num.length;i++){    //从第2个元素开始,此时major和count都有值
 6             if(count==0){    //第一次肯定不进这个循环,因为count初始值位1
 7                 count++;
 8                 major=num[i];
 9             }else if(major==num[i]){
10                 count++;
11             }else count--;    
12         }
13 
14         return major;
15     }
16 }

  举个例子看代码:

  给定数组[1,2,1,2,1,1,3]  初始major =1,count = 1

               第一次循环 count--  count = 0 | 第二次循环 进入count ==0 这个if语句,count =1,major =1|第三次循环 count = 0 | 第四次循环  count =1,major =1|

               第五次循环 count =2,major =1 |第六次循环 count = 1,major =1

               返回 1

  因为 1 出现的次数大于n/2,和其他元素抵消后,剩余的必然是出现次数最多的那个。 要注意的就是 major的设置!!!

 

  代码2:思路2的代码

 1 class Solution {
 2 public:
 3     int majorityElement(vector<int>& nums) {
 4         unordered_map<int, int> counts;     //map
 5         int n = nums.size();
 6         for (int i = 0; i < n; i++)
 7             if (++counts[nums[i]] > n / 2)   //以nums中的不同数字为key,count[数字]为value 
 8                 return nums[i];
 9     }
10 };

 

  首先map的初始化:

  

    具体map的知识参考:http://www.tuicool.com/articles/eqAjIfa

  第七行的代码也等价于如下:

1 for (int i = 0; i < n; i++)
2       ++counts[nums[i]];    //等价于if (++counts[nums[i]] > n / 2)
3       if (counts[nums[i]] > n / 2)
4           return nums[i];

  给定数组[1,2,1,2,1,1,3]  counts[1] = 4 counts[2] = 2 counts[3] = 1,所以说是以数字为key的,以数字出现的次数为value.

  

  代码3:思路3的代码

1 class Solution {
2 public:
3     int majorityElement(vector<int>& nums) {
4         nth_element(nums.begin(), nums.begin() + nums.size() / 2, nums.end());
5         return nums[nums.size() / 2];
6     } 
7 };

  有关:

  •   STL中的nth_element()方法的使用 通过调用nth_element(start, start+n, end) 方法可以使第n大元素处于第n位置(从0开始,其位置是下标为 n的元素),
  •   并且比这个元素小的元素都排在这个元素之前,比这个元素大的元素都排在这个元素之后,但不能保证他们是有序的,
  •   要注意的是,此函数只是将第nth大的元素排好了位置,但并没有返回值,所以要知道第nth大的元素 还得进行一步,cout<<iarray[nth]<<endl; nth既那个位子

   关于nth_element()可参考;http://blog.csdn.net/guofengzai/article/details/2574225

               http://blog.csdn.net/huaxiangsl/article/details/5639437

  我自己的代码:带main函数,可运行

 1 // Majority Element.cpp : 定义控制台应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include "iostream"
 6 #include "unordered_map"    //unordered_map<int, int> counts的头文件
 7 #include "vector"    //vector的头文件
 8 #include "string"    //在这里面貌似没有什么用
 9 #include "algorithm"    //nth_element的头文件
10 using namespace std;
11 /*
12 class MyClass
13 {
14 public:
15     int majorityElement(vector<int>& nums)
16     {
17         int major = nums[0], counts = 1;
18         int n = nums.size();
19         for (int i = 1; i < n; i++)
20         {
21             if (major == nums[i])
22             {
23                 ++counts;
24             }
25             else if (major != nums[i])
26             {
27                 counts--;
28             }
29             else if(counts == 0)
30             {
31                 major = nums[i];
32                 counts = 1;
33             }
34         }
35         return major;
36     }
37 
38 };*/
39 
40 class MyClass
41 {
42 public:
43     int majorityElement(vector<int>& nums)
44     {
45         unordered_map<int, int> counts;
46         for (int i = 0; i < nums.size(); i++)
47         {
48             ++counts[nums[i]];
49             if (counts[nums[i]] > nums.size()/2)    //上面两行和下面的语句等价
50             //if (++counts[nums[i]] > nums.size() / 2)
51                 return nums[i];
52         }
53     }
54 };
55 /*
56 class MyClass
57 {
58 public:
59     int majorityElement(vector<int>& nums)
60     {
61         int n = nums.size();
62         nth_element(nums.begin(), nums.begin() + n / 2, nums.end());    //注意格式必须是nth_element(start, start+n, end)中间数必须是start+n,否则会出错
63         return nums[n / 2];
64     }
65 };*/
66 
67 
68 int _tmain(int argc, _TCHAR* argv[])
69 {
70     vector<int> nums;    
71     nums = { 1, 3, 1, 1, 4, 1, 1 };    //想测非固定输入,但是vector和之前数组不同,暂时不知道怎么写
72     int m;
73     MyClass solution;
74     m = solution.majorityElement(nums);
75     cout << m << endl;
76     system("pause");
77     return 0;
78 }

  运行结果:

  

  vector的动态输入暂时还不知道怎么写,如果后续知道的话,会补上。

   在上节2015.5.18——leetcode:Majority Element中纠结vector的动态输入输出问题,但是发现vector传参型的不可以动态输入输出,但是vector可以,在下一节中附上了代码。

  如果有谁写出了,这道题的动态测试,请告知我,非常感谢!

 

 

 

posted on 2016-05-19 14:39  zhuzhu2016  阅读(153)  评论(0编辑  收藏  举报

导航