我是靠谱客的博主 包容便当,最近开发中收集的这篇文章主要介绍【剑指offer】数组中出现次数超过数组长度一半的数字(三种解法),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。


如果使用时间复杂度为O(n),可以构建hash map,但是应该会存在冲突,并且要设计数据结构
在python3中,如果要让map输出list,在前面要加list,要不然只会返回一个地址

hashList = list(map(hash, [-1.1, -2.6, -2.6, 0, 1, 2]))
print(hashList)
>>>> [-230584300921369601, -1383505805528216578, -1383505805528216578, 0, 1, 2]

后面三种解法时间复杂度都是O(n)


解法1

采用字典的方法,元素对应key,出现的次数对应val
字典API:http://www.runoob.com/python/python-dictionary.html

class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if numbers == []:
            return 0
        dictonary = {}
        dictonary = dictonary.fromkeys(numbers, 0)
        for num in numbers:
            dictonary[num] += 1
        for key in dictonary.keys():
            if dictonary[key] * 2 > len(numbers):
                return key
        return 0

运行时间:29ms

占用内存:5736k


解法2

在上一篇博客中,知道了如何找出数组中第k大个数字。地址:找出数组中任意第k大的数字
如果一个数字的个数超过半数,那么第N/2大的数字一定是这个数字,因此用这个方法找出第N/2大的数字,然后判断这个数字的出现次数是不是满足大于长度的二分之一。(N为数组的长度)

class Solution:
    def partitionOfK(self, numbers, start, end, k):
        if k < 0 or numbers == [] or start < 0 or end >= len(numbers) or k > end:
            return None
        low = start
        high = end
        key = numbers[start]
        while low < high:
            while low < high and numbers[high] >= key:
                high -= 1
            numbers[low] = numbers[high]
            while low < high and numbers[low] <= key:
                low += 1
            numbers[high] = numbers[low]
        numbers[low] = key
        if low < k:
            return self.partitionOfK(numbers, start + 1, end, k)
        elif low > k:
            return self.partitionOfK(numbers, start, end - 1, k)
        else:
            return numbers[low]
    def checkMoreThanHalf(self, numbers, num):
        times = 0
        for number in numbers:
            if num == number:
                times += 1
        if times * 2 <= len(numbers):
            return False
        return True
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if numbers == []:
            return 0
        result = self.partitionOfK(numbers, 0, len(numbers) - 1, len(numbers) >> 1)
        if self.checkMoreThanHalf(numbers, result):
            return result
        else:
            return 0

运行时间:35ms

占用内存:5728k


解法3

数组中如果有一个数字出现的次数超过数组长度的一半,也就是说他出现的次数比其他所有的数字出现的次数的和还要多。因此当我们遍历到下一个数字的时候,如果相同,次数加一,不同次数减一,直到0。如果为0,那么保存下一个数字,并把次数设置为1,找的就是最后设置为1的数字

class Solution:
    def checkMoreThanHalf(self, numbers, num):
        times = 0
        for number in numbers:
            if num == number:
                times += 1
        if times * 2 <= len(numbers):
            return False
        return True
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if numbers == []:
            return 0
        result = numbers[0]
        times = 1
        for i in range(1, len(numbers)):
            if times == 0:
                result = numbers[i]
                times = 1
            elif numbers[i] == result:
                times += 1
            else:
                times -= 1
        if self.checkMoreThanHalf(numbers, result):
            return result
        else:
            return 0

运行时间:25ms

占用内存:5856k

最后

以上就是包容便当为你收集整理的【剑指offer】数组中出现次数超过数组长度一半的数字(三种解法)的全部内容,希望文章能够帮你解决【剑指offer】数组中出现次数超过数组长度一半的数字(三种解法)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部