algo-多数排序

多数排序在leetcode只是一个简单题,但是衍生出来的多种解法却非常有意思

首先是最容易想到的hash和排序算法,接着是

随机化

从概率来讲一个随机挑选一个元素并验证都很大概率是众数

func majorityElementRandom(nums []int) int {
	n := len(nums)
	mc := n / 2
	for {
		candidate := nums[rand.Int63n(int64(n))]
		count := 0
		for _, num := range nums {
			if num == candidate {
				count++
			}
			if count > mc {
				return candidate
			}
		}
	}
}

分治法

分治法是基于数组的众数一定来自于左右子数组的众数之一,因此将数组递归分治最后聚合得到最终的数组多数

func majorityElement(nums []int) int {
	var f func(lo, hi int) int
	f = func(lo, hi int) int {
		// 如果仅有一个元素,那么该元素就是众数
		if lo == hi {
			return nums[lo]
		}

		// 递归数组左右边,找到左右众数
		mid := lo + (hi-lo)/2
		left := f(lo, mid)
		right := f(mid+1, hi)

		// 若左右众数相等,直接返回
		if left == right {
			return left
		}

    // 统计左右众数的个数
		var lc, rc int
		for i := lo; i <= hi; i++ {
			switch nums[i] {
			case left:
				lc++
			case right:
				rc++
			}
		}

    // 比较个数,返回最终众数
		if lc > rc {
			return left
		}
		return right
	}
	return f(0, len(nums)-1)
}

Boyer-Moore

这是本题中最优雅的解法了。设众数+1,非众数-1,那么即使最开始选上的不是众数,由于众数是超过半数的,那么一定在某个众数,发生计数为0的情况,那么此时选上的数就是众数

func majorityElement(nums []int) int {
	var count, candidate int
	for _, num := range nums {
		if count == 0 {
			candidate = num
		}

		if candidate == num {
			count++
		} else {
			count--
		}
	}
	return candidate
}

https://leetcode.cn/problems/majority-element/description/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值