剑指 Offer II 028. 数组中出现次数超过一半的数字

注:本文的代码实现使用的是 JS(JavaScript),为前端中想使用JS练习算法和数据结构的小伙伴提供解题思路。

描述

给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
保证数组输入非空,且保证有解


示例:

输入: [1,2,3,2,2,2,5,4,2]
返回值:2
输入:[3,3,3,3,2,2,2]
输出:3
输入:[1]
输出:1

提示:

  • 数据范围: n < = 5000 n <= 5000 n<=5000,数组中元素的值 0 < = v a l < = 10000 0<= val <= 10000 0<=val<=10000
  • 要求:空间复杂度: O ( 1 ) O(1) O(1),时间复杂度 O ( n ) O(n) O(n)

解题思路

排序法

先把数组排序,出现次数最多的元素一定会在排序后数组的最中间的位置。其复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

function MoreThanHalfNum_Solution(numbers)
{
	// 排序
    numbers = numbers.sort((a,b) => a-b)
    // numbers.length >> 1 ,即向右以一位,相当于除2
    return numbers[numbers.length >> 1]
}

哈希法

使用哈希表对数组中的每一个元素计数,找出个数大于numbers长度的一半的那个元素即可。其时间和空间复杂度都为 O ( n ) O(n) O(n)

function MoreThanHalfNum_Solution(numbers)
{
    let obj = {}
    // 其实在这里整除不整除无所谓,因为是比较元素个数和原数组长度的一半
    let len = numbers.length / 2
    // 统计每个元素出现的个数
    for(const num of numbers){
        if(obj.hasOwnProperty(num)) obj[num] ++
        else obj[num] = 1
    }
    // 直接返回个数大于原数组长度的一半的那个元素
    for(const item in obj){
        if(obj[item] > len) return item
    }
}

指针法

可以定义两个变量,一个num用于存放某个元素,一个count用于存放该元素的个数。遍历number,若num和当前元素相等,则count ++,否则,count --。每次遍历时,判断count是否为0, 若为0,则将当前元素赋值给num,且count =1。这样,最后num所指的元素一定是出现次数超过原数组长度的一半的那个元素。

理由很简单,如果有符合条件的数字,则它出现的次数比其他所有数字出现的次数和还要多。

function MoreThanHalfNum_Solution(numbers)
{
    let num = numbers[0]
    let count = 1
    for(let i = 1, len = numbers.length; i < len; i++){
        if(num !== numbers[i]) count --
        else count ++
        // 这个 if 判断可以放在上一个 if 语句的上面
        if(count === 0) {
            num = numbers[i]
            count = 1
        }
    }
    return num
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值