算法篇:摩尔投票法的使用

时间:2022-07-25
本文章向大家介绍算法篇:摩尔投票法的使用,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

算法:

典型的摩尔投票法使用场景

摩尔投票法分为两个阶段:抵消阶段和计数阶段。

1. 抵消阶段:两个不同投票进行对坑,并且同时抵消掉各一张票,
如果两个投票相同,则累加可抵消的次数;
2. 计数阶段:在抵消阶段最后得到的抵消计数只要不为0,那这个候选人是有可能超过一半的票数的,
 为了验证,则需要遍历一次,统计票数,才可确定。
 备注:对于1/3,1/4.....1/n,做法就是设置n-1个投票候选人,采用摩尔投票的方法进行操作。

题目1: 超过半数的多数元素

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

代码实现:

func majorityElement(nums []int) int {
    tmp,count := 0,0
    for _,num:=range nums {
        if count == 0 {
            tmp = num
        }
        if num == tmp {
            count++
        } else {
            count--
        }
    }
    return tmp
}
// 算法:数组里面有一个数超过一半数量,
// 那么可以用这个数作为标示,这个数就+1,不是这个数就-1,最后剩余的数就是所求

执行结果:

题目2: 求众数

https://leetcode-cn.com/problems/majority-element-ii/

代码实现:

func majorityElement(nums []int) []int {
  // 创建返回值
  var res = make([]int, 0)
  if nums == nil || len(nums) == 0 {
    return res
  }

  // 初始化两个候选人 candidate,以及他们的计数票
  cand1 := nums[0]
  count1 := 0
  cand2 := nums[0]
  count2 := 0

  //摩尔投票法
  // 配对阶段
  for _, num := range nums {
    // 投票
    if cand1 == num {
      count1++
      continue
    }
    if cand2 == num {
      count2++
      continue
    }

    if count1 == 0 {
      cand1 = num
      count1++
      continue
    }
    if count2 == 0 {
      cand2 = num
      count2++
            continue
    }

    count1--
    count2--
  }
  // 计数阶段
  count1 = 0
  count2 = 0
  for _, num := range nums {
    if cand1 == num {
      count1++
    } else if cand2 == num {
      count2++
    }
  }

  if count1 > len(nums)/3 {
    res = append(res, cand1)
  }
  if count2 > len(nums)/3 {
    res = append(res, cand2)
  }
  return res
}
// 算法:摩尔投票法的应用
// 因为是1/3,所以采用2个候选人来进行抉择。

执行结果: