📜  查找多数元素|套装3(位魔术)(1)

📅  最后修改于: 2023-12-03 15:26:37.520000             🧑  作者: Mango

查找多数元素|套装3(位魔术)

本套装包含多个解法,均以位运算为核心思路。通过位运算的巧妙组合,可以在遍历数组的过程中完成对多数元素的查找。

解法1:位计数

通过统计每个数字在每一位上出现的次数,最后找出出现次数大于n/2的数字。优化后的算法时间复杂度为O(n),空间复杂度为O(1)。

def majorityElement(nums: List[int]) -> int:
    res = 0
    n = len(nums)
    for i in range(32):
        cnt = 0
        for num in nums:
            cnt += (num >> i) & 1
        if cnt > n // 2:
            res |= (1 << i)
    return res if res <= 2**31-1 else res - 2**32
解法2:摩尔投票法

摩尔投票法通过遍历数组,记录当前出现次数最多的数字和出现次数,遍历结束后返回出现次数最多的数字即可。时间复杂度为O(n),空间复杂度为O(1)。

def majorityElement(nums: List[int]) -> int:
    count, candidate = 0, None
    for num in nums:
        if count == 0:
            candidate = num
        count += 1 if num == candidate else -1
    return candidate
解法3:分治法

分治法将数组分成左右两部分,分别计算左右两部分的多数元素,然后比较左右两部分的多数元素,返回出现次数最多的数字即可。时间复杂度为O(nlogn),空间复杂度为O(logn)。

def majorityElement(nums: List[int]) -> int:
    def majority(left, right):
        if left == right:
            return nums[left]
        
        mid = (left + right) // 2
        left_majority = majority(left, mid)
        right_majority = majority(mid+1, right)

        if left_majority == right_majority:
            return left_majority

        left_count = sum(1 for i in range(left, right+1) if nums[i] == left_majority)
        right_count = sum(1 for i in range(left, right+1) if nums[i] == right_majority)
        return left_majority if left_count > right_count else right_majority

    return majority(0, len(nums)-1)

以上三种解法均可以高效地找到多数元素。具体使用哪一种解法取决于数据分布情况和效率要求。