Update 169. Majority Element.md

This commit is contained in:
唐树森 2018-09-04 11:25:44 +08:00 committed by GitHub
parent 9ddaa572ba
commit 227919fa70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,51 +1,31 @@
# [169. Majority Element](https://leetcode.com/problems/majority-element/description/) # [169. Majority Element](https://leetcode.com/problems/majority-element/description/)
# 思路 # 思路
题目要求就是求数组主元素,主元素就是在数组中出现次数超过元素个数一半的元素,题目保证主元素一定存在。 题目要求就是求数组主元素,主元素就是在数组中出现次数超过元素个数一半的元素,题目保证主元素一定存在。
## 思路一 ## 思路一: 排序
若对数组nums进行排序则nums[n/2]就是主元素即题目转换成求数组中第n/2小的元素。 若对数组nums进行排序则nums[n/2]就是主元素。
求数组第k小的元素最优的思想应该就是采用类似快排划分的思想 时间复杂度为O(nlogn)。
从数组中随机选择(一般选择第一个)一个元素作为pivot任何进行和快排划分一样的操作后数组被pivot划分为两部分nums[0...m-1]和nums[m+1...n-1], nums[m]=pivot。 ## 思路二: 投票算法
讨论m和k的关系 因为主元素总是存在。所以每出现两个不一样的数就可以忽视这两个数。最终剩下的就是主元素。
(1) 若m=k, 即找到了直接返回pivot 我们可以从前往后遍历如果某数和当前major相同那么count++否则count--如果count为零了那么当前major应该改成当前这个数。
(2) 若m<k, 对nums[m+1...n-1]递归地查找第k-m小的元素(对整个原数组来说还是第k小的元素) 时间复杂度O(n)。
(3) 若m>k, 对nums[0...m-1]递归地查找第k小的元素 ## 思路三: 位运算
该算法平均情况下时间复杂度为O(n), 空间复杂度取决于划分的方法。 如果将每个数都转换为二进制的话那么对于每一位上就只能是0或1。对每一位取出现次数较多的数(0或1),这样组成的数就是主元素。
## 思路二 时间复杂度O(n)。
本题其实是思路一能求解的题目的一个特例。下面介绍更快的方法:
# C++ # C++
## 思路一 ## 思路一
``` ```
// 提交结果为900ms相对于思路二可以说是很慢了 // 提交结果为16ms
class Solution { class Solution {
public: public:
// 定义递归函数
int kth_elem(vector<int>& 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<int>& nums) { int majorityElement(vector<int>& nums) {
int k = nums.size() / 2; sort(nums.begin(), nums.end());
return kth_elem(nums, 0, nums.size() - 1, k); return nums[nums.size() / 2];
} }
}; };
``` ```
## 思路二 ## 思路二
``` ```
// 提交结果为12ms较思路一有大幅提升 // 提交结果为12ms较思路一有提升
class Solution { class Solution {
public: public:
int majorityElement(vector<int>& nums) { int majorityElement(vector<int>& nums) {
@ -59,3 +39,23 @@ public:
} }
}; };
``` ```
## 思路三
```
// 提交结果20ms
class Solution {
public:
int majorityElement(vector<int>& nums) {
vector<int>bit(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;
}
};
```