剑指Offer系列——数组中出现次数超过一半的数字

地址

https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=13&tqId=11181&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking

题目

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

思路

1.中位数思想
满足题目要求的数组经排序后,中间元素一定是结果,所以最简单的方法就是对数组进行排序,然后获取中间元素。因为这个题的用例有点问题,里面还有不满足这种要求的数组,所以获得结果后需要遍历数组进行验证。时间复杂度O(NlogN)

import java.util.Arrays;
public class Solution {
    public int MoreThanHalfNum_Solution(int [] a) {
        if(a == null || a.length == 0) return 0;
        //排序
        Arrays.sort(a);
        //如果存在这个数,那么这个数一定在正中间
        int res = a[a.length/2];
        
        //因为测试用例有可能会有不存在的,所以需要验证
        int count = 0;
        for(int i : a){
            if(i == res)
                count++;
        }
        return count > a.length / 2?res:0;
    }
}

2.计数法
当然了,第一种方法不是最优解,因为使用了排序。根据题目要求已知,如果满足要求的结果在数组中的个数一定比其他元素的个数总和多,所以我们可以设立两个变量,一个用于计数,一个用于储存当前元素。从第二个元素开始逐个比较,如果前一个元素等于当前元素,则计数器加1,否则计数器减1。如果计数器为0,则重新给两个变量赋值:计数器设置为1,当前变量储存,最后的结果一定是满足要求的元素。时间复杂度:O(N)。

public class Solution {
    public int MoreThanHalfNum_Solution(int [] a) {
        if(a == null || a.length == 0) return 0;
        
        int count = 1;
        int res = a[0];
        for(int i = 1;i < a.length;i++){
            if(count == 0){
                //换成当前数
                res = a[i];
                count = 1;
            }
            if(res != a[i]){
                count--;
            }else{
                count++;
            }
        }
        
        //因为测试用例有可能会有不存在的,所以需要验证
        count = 0;
        for(int i : a){
            if(i == res)
                count++;
        }
        return count > a.length / 2?res:0;
        
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值