牛客-数组中出现次数超过一半的数字

📜个人简介

⭐️个人主页:摸鱼の文酱博客主页🙋‍♂️
🍑博客领域:java编程基础,mysql
🍅写作风格:干货,干货,还是tmd的干货
🌸精选专栏:【Java】【mysql】 【算法刷题笔记】
🎯博主的码云gitee,平常博主写的程序代码都在里面。
🚀支持博主:点赞👍、收藏⭐、留言💬
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!

文章目录

<font color=>📃

🎯1.原题链接

数组中出现次数超过一半的数字

🎯2.题目要求

  给一个长度为 n的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
  例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2
  数据范围: 50000n≤50000,数组中元素的值100000≤val≤10000
  要求:空间复杂度:O(1),时间复杂度 O(n)

  样例输入: [1,2,3,2,2,2,5,4,2]

  样例输出: 2

🎯3.基础框架

java版本的基础框架代码如下:

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        
    }
}

🎯4.解题思路

思路一:类似"桶排序"思想

  1.先创建一个大小10001的数组counts,元素都为0;
  2.遍历原数组,遍历到数字n,就把counts中该数为下标的元素加一
  3.最后遍历counts数组,与array数组长度的一半做对比,如果发现 c o u n t s [ i ] > a r r a y . l e n g t h / 2 counts[i] > array.length/2 counts[i]>array.length/2,将该数对应下标返回.

思路二:先排序后取数组中间的那个数

  1.先对数组进行排序
  2.取数组中间的那个数
数组排序后,如果符合条件的数存在,则一定是数组中间那个数。这种方法虽然容易理解,但由于涉
及到快排sort,其时间复杂度为O(NlogN)并非最优;

思路三:谁多谁留下

  1.如果两个数不相等,就消去这两个数
  2最后留下的数肯定是众数。

🎯5.完整代码

解法一:

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        int[] counts=new int[10001];
        for (int arr : array){
            counts[arr]++;
        }
        int number = 0;
        for (int arr :counts){
           if (arr > array.length/2){
               break;
           }
           number++;
        }
        return number;
    }
}

解法二:

public int MoreThanHalfNum_Solution4(int [] array) {
        if(array == null || array.length == 0) {
            return 0;
        }
        Arrays.sort(array);
        int len = array.length;
        int midNum = array[len/2];
        int count = 0;
        for(int i = 0;i < len;i++) {
            if(array[i] == midNum) {
                count++;
            }
        }
        if(count > len/2) {
            return midNum;
        }
        return 0;
    }

解法三:

public class Solution {
    public static int MoreThanHalfNum_Solution(int [] array) {
        if(array == null || array.length==0) {
            return 0;
        }
        int result = array[0];
        int times = 1; // 次数
        for(int i=1;i<array.length;++i){
            if(times != 0){
                if(array[i] == result) {
                    ++times; // 相同则加1
                }else{
                    --times; // 不同则减1
                    }
            }
            else {
                // 更新result的值为当前元素,并置次数为1
                result = array[i];
                times = 1;
            }
        }
        // 判断result是否符合条件,即出现次数大于数组长度的一半
                times = 0;
        for(int i=0;i<array.length;++i){
            if(array[i] == result) ++times;
        }
        return (times > array.length/2) ? result : 0;
    }
}

🎯6.涉及算法&思想&总结

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值