zoukankan      html  css  js  c++  java
  • 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.

    这是一道编程之美和剑指offer上都有的题目。

    直观的思路先对数组进行排序,则中间index上存储的数一定是该出现次数超过一半的数字。但是这种操作的时间复杂度为为排序的时间复杂度O(nlogn),不是很理想。

    另外一种思路是思路是对快排的改进,即我们不需要对数组进行彻底排序,只需要找到那个在最终排序完的数组中的中间index的那个元素。使用QuickSort的partition来完成这种任务很合适。每次partition会找到 pivot所在的index,可以通过不断二分选择,使最终的pivot的index为(left+right)/2达到目的。

    算法时间复杂度平均情况下为O(n)。也是devide and conquer分治的思想。

    另外一种思路是既然该数字在数组中出现次数超过一半,则该数字的出现次数比其他所有数字的次数都多。则每次删除数组中两个不同的数,留下的数组中该数字的出现次数依然超过一半。

    具体实现时并不是真正去两两删除,而是用一个times和一个result来模拟。result保存数组中的数字,times保存出现的次数。如果下一个数字和我们保存的result中的值不一样,则times的值减1,否则times加1,如果当前times为0,则将result的值赋为当前值,最终result的值为那个出现出现次数超过一半的数的值。代码如下:

    class Solution(object):
        def majorityElement(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            times = 1        #开始times初始化
            result = nums[0] #
            for i in nums[1:]:
                if times == 0:
                    result = i #重新开始
                    times = 1  #重新开始计数
                else:
                    if result == i:
                        times += 1
                    else:
                        times -= 1
            return result

    注意如何把这段代码和两两删除不同的元素对应上。实际上从result赋值,times为1,到times降为0这个过程,实现的就是删除元素的过程。比如1234,1到2时,times为0,3时times重新等于1,record为3,4时times又降为0,其实就是两两删除的过程。如果有连续值,555534216,则到1时,times也降为0,相当于(5,3),(5,4),(5,2),(5,1)两两删除了。所以在最后一个 times为1,record换值时,record就是那个出现超过一半的数字,一直到数组尾部,也没有那么多和record不同的元素来和它抵消。算法成立。

  • 相关阅读:
    PHP迭代器
    PDO

    五种常见的 PHP 设计模式
    php fastcgi_finish_request 函数的理解
    vagrant up 启动虚拟机报错
    thrift php 的使用
    python 基本知识学习(一)
    PHP实现进程间通信:消息队列 msg_get_queue 函数不存在
    [转]Python函数的各种参数用法(含星号参数)
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5474233.html
Copyright © 2011-2022 走看看