LeetCode---169.求众数

题目来源:https://leetcode-cn.com/problems/majority-element/description/

题目描述:

算法描述:对于该题目,可能有些人想到的就是最暴力的穷举,但是时间复杂度为O(n2)。所以我们不用那种方法。我们可以可以使用分治算法实现也可以用摩尔投票法。

第一种.分治算法实现:

分治法是将整个问题化简为一个一个的小问题去解,将数组分成简单的几部分,比如讲一组数分为两部分,第一部分的众数如果等于第二部分的众数,则这个数就是上一层那一组的众数,如果第一部分不等于第二部分,则遍历这一组数,比较第一部分的众数和第二部分的众数哪个出现频率高,频率高的这个数就是这一组数的众数。

代码如下:

class Solution {
	public int majorityElement(int[] nums) {
		return find(nums, 0, nums.length - 1);
	}

	public static int find(int[] nums, int begin, int end) {
		if (begin == end || begin + 1 == end)
			return nums[begin];
		else {
			//这里主要是为了把数组一分为二(这里就体现了分治算法的思想)
			int mid = (begin + end) / 2;
			//leftNum就是一个数组中,左半部分的众数
			int leftNum = find(nums, begin, mid);
			//rightNum就是一个数组中,左半部分的众数
			int rightNum = find(nums, mid + 1, end);
			// 左右两部分的众数相同 则这个数是当前这个数组的众数
			if (leftNum == rightNum) {
				return leftNum;
			}else {
				// 左右两部分的众数不相同 则这两个数都有可能是这部分的众数
				// 那么遍历这个数组 看一下哪个数字的出现频率高,频率高的为当前这个数组的众数
				int countLeft = 0;
				int countRight = 0;
				for (int i = begin; i <= end; i++)
					if (nums[i] == leftNum)
						countLeft++;
					else if (nums[i] == rightNum)
						countRight++;

				if (countLeft > countRight)
					return leftNum;
				else
					return rightNum;
			}
		}
	}
}

第二种.摩尔投票法实现:

摩尔投票法的基本思想很简单,在每一轮投票过程中,从数组中找出一对不同的元素,将其从数组中删除。这样不断的删除直到无法再进行投票,如果数组为空,则没有任何元素出现的次数超过该数组长度的一半。如果只存在一种元素,那么这个元素则可能为目标元素。那么有没有可能出现最后有两种或两种以上元素呢?根据定义,这是不可能的,因为如果出现这种情况,则代表我们可以继续一轮投票。因此,最终只能是剩下零个或一个元素。

代码如下:

class Solution {
	public int majorityElement(int[] nums) {
		int result = nums[0], count = 0;
		for (int num : nums) {
			if (count == 0) {
				result = num;
				count++;
			} else {
				if (result == num) {
					count++;
				} else {
					count--;
				}
			}
		}
		return result;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_39241239/article/details/82871294