Majority Vote Alogrithm 多数投票算法
2016-12-25 22:44
549 查看
当一个序列中存在一个占大多数的的元素的时候(超过50%),该算法可以在O(1)空间和O(n)时间内找出这个元素。
Tips: ⌊ 59/60⌋ = 0, floor(),向下取整
You may assume that the array is non-empty and the majority element always exist in the array.
超过 ⌊ n/3 ⌋,那就每次从数组里面删除三个不一样的元素。
count 为 candidate 当前出现的次数。count == 0 说明当前 candidate 对应的候选者已经被移除,我们需要设定一个新的候选者。
问题一: if 的判定顺序有要求吗?如果有要求的话应该是怎么样的呢?
答案是有要求,细心的读者可能发现,在 Majority Element 中,我们对 count == 0 的判断在对 candidate == nums[i] 的判断之前,而在 Majority Element II 中则正好相反。
这是因为,count == 0 是用来判断对应 candidate 的当前存活量,在判断这一步之前,我们必须确保数组中当前数字不等于 两个 candidate中的任意一个。否则,我们可能会在 count0!=0 && count1==0 && nums[i]==candidate0 时错误的将 nums[i] 赋值给 candidate1。
问题二:这里给 candidate0 candidate1 初始化值为 0,这会不会影响我们运行的结果?
不会,因为 candidate0 只会在第一次循环中使用,如果 candidate0 == nums[0],count++不会引起任何问题。如果 candidate != nums[0] 那么我们此时 count==0 重新初始化 candidate0 == nums[0],同样不会有任何影响。
问题二扩充:如果我们初始化 int candidate0 = 0, candidate1 = 1 会不会影响我们的运行结果呢?
问题三:这里能够省略 distinct() 吗?为什么?
不能,尽管我们在循环中首先通过 if(candidate0 == nums[i]) 和 else if(candidate1 == nums[i]) 两个 if 判断,使得 candidate0 != candidate1 在绝大部分下成立,但是在一种极为特殊的情况下仍然可能会使得我们得到重复的数组。
试想当整个数组所有的数字都相等的时候,我们 candidate0 和 candidate1 这两个候选数字中,有一个数字将永远不会被重新赋值,也就是说,有一个数字将我们赋给的初值保持到了最后。
在我们的代码中,因为我们将两个候选数字都初始化 0,所以当数组 全为0 时会返回错误的结果。
这一点,我们可以通过将两个候选数字初始化为不同的数字来解决:int candidate0 = 0,candidate1 = 1,这样我们就可以移除掉 distinct() 了
Tips: ⌊ 59/60⌋ = 0, floor(),向下取整
Majority Element
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.You may assume that the array is non-empty and the majority element always exist in the array.
Majority Element II
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.Analysis
大致思路就是,比如超过数组一半元素以上的element,可以每次从数组删除2个不一样的元素,那么最后剩下的一定就是major element。超过 ⌊ n/3 ⌋,那就每次从数组里面删除三个不一样的元素。
Code
Majority Element
public class Solution { public int majorityElement(int[] nums) { int count = 0; int target =0 ; for(int i=0; i<nums.length; i++){ if(count==0){ count++; target = nums[i]; } else if(nums[i]==target){ count++; } else{ count--; } } return target; } }
Majority Element II
思路依然同 Majority Element 一样,不同的是我们需要两个 Majority Element 的候选者,同时需要两个 count 分别对候选者进行计数。count 为 candidate 当前出现的次数。count == 0 说明当前 candidate 对应的候选者已经被移除,我们需要设定一个新的候选者。
public class Solution { public List<Integer> majorityElement(int[] nums) { List<Integer> result = new ArrayList<Integer>(); int count1 = 0, count2 = 0; int target1 = 0 ,target2 = 1; for(int i=0; i<nums.length; i++){ if(nums[i]==target1){//当前数字等于1号候选数字 count1++; } else if(nums[i]==target2){//当前数字等于2号候选数字 count2++; } else if(count1==0){ //当前数字不等于1,2号候选数字,且1号候选数字可以被重新选择 count1++; target1 = nums[i]; } else if(count2==0){//当前数字不等于1,2号候选数字,且2号候选数字可以被重新选择 count2++; target2 = nums[i]; } else{//删除三个互相不一样的元素 count1--; count2--; } } count1 = 0; count2 = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == target1) count1++; else if (nums[i] == target2) count2++; } if (count1 > nums.length / 3) result.add(target1); if (count2 > nums.length / 3) result.add(target2); return result; } }
一些思考
以下部分via Majority Vote Alogrithm(最大投票算法)及其扩展问题一: if 的判定顺序有要求吗?如果有要求的话应该是怎么样的呢?
答案是有要求,细心的读者可能发现,在 Majority Element 中,我们对 count == 0 的判断在对 candidate == nums[i] 的判断之前,而在 Majority Element II 中则正好相反。
这是因为,count == 0 是用来判断对应 candidate 的当前存活量,在判断这一步之前,我们必须确保数组中当前数字不等于 两个 candidate中的任意一个。否则,我们可能会在 count0!=0 && count1==0 && nums[i]==candidate0 时错误的将 nums[i] 赋值给 candidate1。
问题二:这里给 candidate0 candidate1 初始化值为 0,这会不会影响我们运行的结果?
不会,因为 candidate0 只会在第一次循环中使用,如果 candidate0 == nums[0],count++不会引起任何问题。如果 candidate != nums[0] 那么我们此时 count==0 重新初始化 candidate0 == nums[0],同样不会有任何影响。
问题二扩充:如果我们初始化 int candidate0 = 0, candidate1 = 1 会不会影响我们的运行结果呢?
问题三:这里能够省略 distinct() 吗?为什么?
不能,尽管我们在循环中首先通过 if(candidate0 == nums[i]) 和 else if(candidate1 == nums[i]) 两个 if 判断,使得 candidate0 != candidate1 在绝大部分下成立,但是在一种极为特殊的情况下仍然可能会使得我们得到重复的数组。
试想当整个数组所有的数字都相等的时候,我们 candidate0 和 candidate1 这两个候选数字中,有一个数字将永远不会被重新赋值,也就是说,有一个数字将我们赋给的初值保持到了最后。
在我们的代码中,因为我们将两个候选数字都初始化 0,所以当数组 全为0 时会返回错误的结果。
这一点,我们可以通过将两个候选数字初始化为不同的数字来解决:int candidate0 = 0,candidate1 = 1,这样我们就可以移除掉 distinct() 了
相关文章推荐
- Boyer–Moore majority vote algorithm 博耶-穆尔多数投票算法 leetcode第229题
- 转载-Array-Majority Vote Alogrithm(最大投票算法)及其扩展
- 多数投票算法(Majority Vote Algorithm)
- 多数投票算法 --- A linear time majority vote algorithm
- 多数投票算法 Majority Vote Algorithm
- leetcode 169. Majority Element 多数投票算法(Boyer-Moore Majority Vote algorithm)
- 多数投票算法 Majority Vote Algorithm
- 多数投票算法 Majority Vote Algorithm
- 【LeetCode】169. Majority Element (多数投票算法 & 算法迁移能力)
- Moore majority vote algorithm(摩尔投票算法)
- LeetCode--Majority Element II & 多数投票算法
- LeetCode--Majority Element II & 多数投票算法
- 摩尔投票算法(Boyer–Moore majority vote algorithm)
- Moore majority vote algorithm(摩尔投票算法)
- 字符串算法——查找数组多数元素(Majority Element II)
- 多数投票算法
- Boyer and Moore Fast majority vote algorithm(快速选举算法)
- 多数投票算法
- Boyer_Moore算法(多数投票算法)
- LeetCode:Majority Element I II 投票算法