《leetCode》:Majority Element II

来源:互联网 发布:淘宝开店流程及费用 编辑:程序博客网 时间:2024/06/16 11:11

题目

Given an integer array of size n, find all elements that appear more than ⌊ n/3times. The algorithm should run in linear time and in O(1) space.

思路

这个题不会做也,下面思路来源于:https://leetcode.com/discuss/82195/quick-select-c-solution

The idea is to split the array into three parts according to the selected pivot: left, middle and right.Let's say we have two indices m and n, so that all elements in [0 ... m-1] are less than the pivot, elements in [m...n] are equal to the pivot (two ends inclusive), [n+1 ... end] contains elements greater than the pivot. Then there are some facts:if n - m + 1 >= 1 + nums.size()/3, nums[m] must be added to the results.If m - 1 < 1 + nums.size()/3, we can simply abandon the left part, otherwise we have to consider it.if nums.size()-n < 1+nums.size()/3, the right part can be dropped, otherwise it has to be checked.Ideally, we can drop about 1/3 of the array each time, so the running time is something like: 1 + 2/3 + (2/3)*(2/3) + ... = (1-(2/3)^k)/(1-2/3), O(n).A big advantage of this algorithm is that we can simply apply it to 1/4,1/5 ...

实现代码如下:

/** * Return an array of size *returnSize. * Note: The returned array must be malloced, assume caller calls free(). */int *res=NULL;int indexRes=0; void swap(int *a,int *b){    int temp=*a;    *a=*b;    *b=temp;} void majorityElementHelper(int *nums,int left,int right,int len){    if(nums==NULL||right<left){        return;    }    //选取mid位置的值作为pivot值     int mid=(left+right)/2;    int val=nums[mid];    int m=left;//用来指示 调整后的结果中,m左边的值都是小于val的。     int n=left;//用来指示  调整后的结果中,m~n中的值都是等于val的。n~right都是大于val的     swap(nums+left,nums+mid);//将pivot放入nums第一个位置     int i=left+1;    while(i<=right){        if(nums[i]<val){            swap(&nums[m++],&nums[i]);//将小于val的值放入m下标的左边             swap(&nums[++n],&nums[i++]);//使得n总是指向最右边的等于val的下标         }        else if(nums[i]==val){            swap(&nums[++n],&nums[i++]);        }        else{            i++;        }    }    if(n-m+1>=len){//符合条件         res[indexRes++]=nums[n];    }     if(m-left>=len){//小于val的长度大于len,因此可能有解         majorityElementHelper(nums,left,m-1,len);    }    if(right-n>=len){//大于val的长度大于len,因此可能有解         majorityElementHelper(nums,n+1,right,len);    }}int* majorityElement(int* nums, int numsSize, int* returnSize) {    if(nums==NULL||numsSize<1){        *returnSize=0;        return NULL;    }    int maxLen=3;//最多只有三个解     res=(int *)malloc(maxLen*sizeof(int));    if(res==NULL){        exit(EXIT_FAILURE);    }    indexRes=0;     majorityElementHelper(nums,0,numsSize-1,(numsSize/3)+1);    *returnSize=indexRes;    return res; }
1 0