维基百科

    背景:找出一组数字序列中出线次数大于总数 1/2 的数字(并假设一定存在这个数字)。显然这个数字只存在一个。

    每次从序列出选择两个不相同的数字删掉(或者是“抵消”),最后剩下的一个数字或几个相同的数字,就是出现次数大于总数一半的那个。

    中心思想就是:删除,删除,删除,直到不能删除为止。

    维护两个变量,分别是最后的结果 res 和计数值 count ,其实这俩变量表达的是一个隐形的数组,数组中存储的是 当前暂时无法删除的数字 也就是 res count 表示数组的长度

    伪代码

    • 初始化元素m并给计数器i赋初值i = 0
    • 对于输入队列中每一个元素x
      • i = 0, 那么 m = x and i = 1
      • 否则若m = x, 那么 i = i + 1
      • 否则 i = i − 1
    • 返回 m

    举个栗子

    1. 输入 {1,2,1,3,1,1,2,1,5}
    2. res = 0 count = 0
    3. 1步:没有元素可以跟当前的结果抵消
    4. 当前值 curr 1,,count == 0 ,所以 res = curr(1),count++(1)
    5. 2步:当前值 curr 2,当前值不等于 res,所以抵消掉当前结果,可以暂时不修改res 的结果
    6. count != 0 && res != curr,所以 res 保持不变(1), count--(0)
    7. 3步:当前值 curr 1count == 0 当前值不等于 res,所以抵消掉当前结果,可以暂时不修改res 的结果
    8. count == 0,所以 res = curr(1), count++(1)
    9. 4步:当前值 curr 3 count != 0 && res != curr, 所以 res 保持不变(1), count--(0)
    10. 5步:当前值 curr 1 count == 0, 所以 res = 1, count++(1)
    11. 6步:当前值 curr 1 count == 0 ,所以 res = curr(1),count++(2)
    12. 7步:当前值 curr 2 count != 0 && res != curr, 所以 res 保持不变(1),count--(1)
    13. 8步:当前值 curr 1 count == 0, 所以 res = curr(1),count++(2)
    14. 9步:当前值 curr 5 count != 0 && res != curr, 所以 res 保持不变(1),count--(1)

    超过 1/3 的 众数

    1. package main
    2. // @lc code=start
    3. func majorityElement(nums []int) []int {
    4. target := len(nums) / 3
    5. cur1, cur2 := 0, 0
    6. count1, count2 := 0, 0
    7. for _, val := range nums {
    8. if cur1 == val && count1 > 0 {
    9. count1++
    10. } else if cur2 == val && count2 > 0 {
    11. count2++
    12. } else if count1 == 0 {
    13. cur1 = val
    14. count1++
    15. } else if count2 == 0 {
    16. cur2 = val
    17. count2++
    18. } else {
    19. count1--
    20. count2--
    21. }
    22. }
    23. count1, count2 = 0, 0
    24. for _, val := range nums {
    25. if val == cur1 {
    26. count1++
    27. } else if val == cur2 {
    28. count2++
    29. }
    30. }
    31. res := make([]int, 0)
    32. if count1 > target {
    33. res = append(res, cur1)
    34. }
    35. if count2 > target {
    36. res = append(res, cur2)
    37. }
    38. return res
    39. }