剑指offer39 数组中出现次数超过一半的数字

首先暴力解法:对每个数字统计次数,O(n^2)。

如果排序后统计次数,只需要O(n),加上排序O(nlogn)。

然后空间换时间:设置HashMap统计数字次数,时间O(n)空间O(n)。

剑指offer思路一:基于快排的思路,书上说时间复杂度是O(n),我觉得还是O(nlogn),所以和排序思路不相上下,感觉也就那样吧,还很复杂。思路二非常不错。

思路二:目标数字出现次数超过一半,也就是其出现次数超过其他所有数字的出现次数之和。那么我们设置两个变量,一个记录遍历到的数字,另一个记录出现次数。

如果遍历到的数字和保存的数字相同,则次数+1,如果不相同,则次数-1。次数==0,则保存下一个遍历的数字。

另外要注意检查找到的数字是不是真的出现超过一半。

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        if(array==null||array.length<1) return 0;
        
        int object = array[0];
        int count = 1;
        for(int i=1;i<array.length;i++){
            if(count==0) {object = array[i];count++;}
            if(array[i]==object) count++;
            else count--;
        }
        if(isRealAns(array,object)) return object;
        else return 0;
    }
    private boolean isRealAns(int[] array,int object){
        int count = 0;
        for(int i=0;i<array.length;i++){
            if(array[i]==object) count++;
        }
        return count>array.length/2?true:false;
    }
}

最后要检查输入数组是否存在一下情况:

[1,2,3,2,4,2,5,2,3]

所以要加个判断。

运行时间:19ms

占用内存:9212k

 

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if numbers is None or len(numbers)<1:
            return 0
        ans = numbers[0]
        count = 1
        for i in range(1,len(numbers)):
            if count == 0:
                ans = numbers[i]
                count = 1
                continue
            if numbers[i]==ans:
                count+=1
            else:
                count-=1
        if self.isRealAns(numbers,ans):
            return ans
        else:
            return 0
        
    def isRealAns(self,numbers,ans):
        cnt = 0 
        for num in numbers:
            if num == ans:
                cnt+=1
        if cnt>len(numbers)/2:
            return True
        else:
            return False

运行时间:33ms

占用内存:6236k

posted @ 2019-02-27 15:32  大胖子球花  阅读(92)  评论(0)    收藏  举报