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.
Example 1:
Input: [3,2,3]
Output: 3
Example 2:
Input: [2,2,1,1,1,2,2]
Output: 2
题目要求输出出现次数超过总长度一半的数。
首先想到的是排序,但自己排序之后的做法还是更古板了一些。
class Solution {
public int majorityElement(int[] nums) {
int n=nums.length/2;
Arrays.sort(nums);
int temp=nums[0];
int count=0;
for(int i=0;in) return temp;
}
else{
count=1;
temp=nums[i];
}
}
return 0;
}
}
以下均为solution部分的解法:
更加明了的做法是直接输出一半处的内容!
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
}
要求找的是出现次数多于一半的数,那么在这些数中随便找一个数,是最终结果的概率超过一半。
对找到的这个数遍历整个数组进行验证,如果超过一半的话那就是它了!
可以说是很妙了,时间复杂度为O(无穷),机智当中又透漏着那么点皮~
class Solution {
private int randRange(Random rand,int min,int max){
return rand.nextInt(max-min)+min;
}
private int countOccurences(int[] nums,int num){
int count=0;
for(int i=0;imajorityCount)
return candidate;
}
}
}
class Solution {
private int countInRange(int[] nums,int num,int lo,int hi){
int count=0;
for(int i=lo;i<=hi;i++){
if(nums[i]==num)
count++;
}
return count;
}
private int majorityElementRec(int[] nums,int lo,int hi){
//base case
//如果这一部分数组里只有一个元素,那么就返回这个元素
if(lo==hi)
return nums[lo];
//recurse
//递归选出左边和右边出现次数最多的元素
int mid=(hi-lo)/2+lo; //求mid的时候用这种方法可以有效的防止溢出
int left=majorityElementRec(nums,lo,mid);
int right=majorityElementRec(nums,mid+1,hi);
//如果在两边都是出现次数最多的,那么在整体也是出现次数最多的
if(left==right)
return left;
//count each element and return the winner
//如果两边出现出现次数最多的不是同一个元素,那么就在这部分整体(从lo到hi)数,返回出现最多的那个元素
int leftCount=countInRange(nums,left,lo,hi);
int rightCount=countInRange(nums,right,lo,hi);
return leftCount>rightCount?left:right;
}
public int majorityElement(int[] nums) {
return majorityElementRec(nums,0,nums.length-1);
}
}
基本的思想是,遇到一个复杂的问题,就把它拆成一小部分一小部分的来,如果在每一部分都是出现的最多的,那肯定是最多的,如果每一部分出现最多的不是同一个,那就数一数,看他们哪一个在整体是出现最多的。
很巧妙的是,如果这个部分的两个元素出现次数是一样多的的话,那随便选一个也不会出错,因为有另一边和最后的检查步骤在那里卡着,是不会出错的!
https://blog.csdn.net/kimixuchen/article/details/52787307
class Solution {
public int majorityElement(int[] nums) {
int count = 0;
Integer candidate = null;
for (int num : nums) {
if (count == 0) {
candidate = num;
}
count += (num == candidate) ? 1 : -1;
}
return candidate;
}
}
从candidate被赋值到count变为0的这一部分是可以相互抵消的。
多数排序算法要遍历两次数组,第一次确定candidate,第二次确定candidate是否是出现次数超过一半的,题目已经假设这个数存在,所以只需遍历一遍数组。
时间复杂度为O(n),空间复杂度为O(1)