From 227919fa70b79bf93fba88afeccf58d5b16504ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=A0=91=E6=A3=AE?= <14021051@buaa.edu.cn> Date: Tue, 4 Sep 2018 11:25:44 +0800 Subject: [PATCH] Update 169. Majority Element.md --- 169. Majority Element.md | 68 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/169. Majority Element.md b/169. Majority Element.md index 0e8440f..2c0937c 100644 --- a/169. Majority Element.md +++ b/169. Majority Element.md @@ -1,51 +1,31 @@ # [169. Majority Element](https://leetcode.com/problems/majority-element/description/) # 思路 题目要求就是求数组主元素,主元素就是在数组中出现次数超过元素个数一半的元素,题目保证主元素一定存在。 -## 思路一 -若对数组nums进行排序,则nums[n/2]就是主元素,即题目转换成求数组中第n/2小的元素。 -求数组第k小的元素最优的思想应该就是采用类似快排划分的思想: -从数组中随机选择(一般选择第一个)一个元素作为pivot任何进行和快排划分一样的操作后,数组被pivot划分为两部分nums[0...m-1]和nums[m+1...n-1], nums[m]=pivot。 -讨论m和k的关系: -(1) 若m=k, 即找到了,直接返回pivot; -(2) 若mk, 对nums[0...m-1]递归地查找第k小的元素; -该算法平均情况下时间复杂度为O(n), 空间复杂度取决于划分的方法。 -## 思路二 -本题其实是思路一能求解的题目的一个特例。下面介绍更快的方法: +## 思路一: 排序 +若对数组nums进行排序,则nums[n/2]就是主元素。 +时间复杂度为O(nlogn)。 +## 思路二: 投票算法 +因为主元素总是存在。所以每出现两个不一样的数就可以忽视这两个数。最终剩下的就是主元素。 +我们可以从前往后遍历,如果某数和当前major相同那么count++,否则count--,如果count为零了,那么当前major应该改成当前这个数。 +时间复杂度O(n)。 +## 思路三: 位运算 +如果将每个数都转换为二进制的话,那么对于每一位上就只能是0或1。对每一位,取出现次数较多的数(0或1),这样组成的数就是主元素。 +时间复杂度O(n)。 # C++ ## 思路一 ``` -// 提交结果为900ms,相对于思路二可以说是很慢了 +// 提交结果为16ms class Solution { public: - // 定义递归函数 - int kth_elem(vector& nums, int low, int high, int k){ - int pivot=nums[low]; - int low_bk=low, high_bk = high; // 后面要修改low和high,所以先备份 - while(low < high){ - while(low < high && nums[high] >= pivot) high--; - nums[low] = nums[high]; - while(low < high && nums[low] <= pivot) low++; - nums[high] = nums[low]; - } // low==high 退出循环 - nums[low]=pivot; - // 以上为快排划分思想 - - if(low == k) return pivot; - else if(low > k) return kth_elem(nums, low_bk, low-1, k); - else return kth_elem(nums, low+1, high_bk, k); - } - int majorityElement(vector& nums) { - int k = nums.size() / 2; - return kth_elem(nums, 0, nums.size() - 1, k); - + sort(nums.begin(), nums.end()); + return nums[nums.size() / 2]; } }; ``` ## 思路二 ``` -// 提交结果为12ms,较思路一有大幅提升 +// 提交结果为12ms,较思路一有提升 class Solution { public: int majorityElement(vector& nums) { @@ -59,3 +39,23 @@ public: } }; ``` +## 思路三 +``` +// 提交结果20ms +class Solution { +public: + int majorityElement(vector& nums) { + vectorbit(32); + for (int num: nums){ + for (int i = 0; i < 32; i++) + if(num & (1 << i)) bit[i]++; + } + + int major=0; + for (int i = 0; i < 32; i++) { + if(bit[i] = bit[i] > nums.size() / 2) major += bit[i] * (int)pow(2, i); + } + return major; + } +}; +```