diff --git a/169. Majority Element.md b/169. Majority Element.md new file mode 100644 index 0000000..0e8440f --- /dev/null +++ b/169. Majority Element.md @@ -0,0 +1,61 @@ +# [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), 空间复杂度取决于划分的方法。 +## 思路二 +本题其实是思路一能求解的题目的一个特例。下面介绍更快的方法: +# C++ +## 思路一 +``` +// 提交结果为900ms,相对于思路二可以说是很慢了 +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); + + } +}; +``` +## 思路二 +``` +// 提交结果为12ms,较思路一有大幅提升 +class Solution { +public: + int majorityElement(vector& nums) { + int major = nums[0], count = 0; + for(int num : nums){ // 范围for语句 + if(major == num) count++; + else if(count == 1) major = num; + else count--; + } + return major; + } +}; +```