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

这篇具有很好参考价值的文章主要介绍了剑指 Offer 39.数组中出现次数超过一半的数字。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:
输入:nums = [3,2,3]
输出:3
示例 2:

输入:nums = [2,2,1,1,1,2,2]
输出:2

提示:
n == nums.length
1 <= n <= 5 * 104
-109 <= nums[i] <= 109

进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。


思路一

将数组进行排序,中间那个元素,就是所要找的值

本题使用插入排序
数据结构与算法—排序—插入排序、二分搜索

class Solution {
    public int majorityElement(int[] nums) {
        //边界条件
        if(nums == null) return 0;
        if(nums.length == 1) return nums[0];

        insertSort(nums);
        //或者使用系统自带排序算法
        //Arrays.sort(nums);

        int middleIndex = nums.length/2;
        int result = nums[middleIndex];
         
        return result; 
    }

    //插入排序
    public static void insertSort(int[] nums) {
        if(nums == null) return;

        for (int preInsertIndex = 1; preInsertIndex < nums.length; preInsertIndex++)
        {
            int saveValue = nums[preInsertIndex];
            for(int sortedIndex = preInsertIndex; sortedIndex > 0; sortedIndex--){
                if(nums[sortedIndex - 1] > saveValue){
                    nums[sortedIndex] = nums[sortedIndex - 1];
                }else{
                    nums[sortedIndex] = saveValue;
                    break;
                }

                if(sortedIndex == 1){
                    nums[0] = saveValue;
                }
            }
        }
    }
}

思路二

运用哈希表,将每个元素的值放入哈希表中,如果继续增加,则+1,同时记录最大值,以及最大元素
参考:
数据结构与算法—在一个数组中找出相同个数最多的数

以上两种做法,都不能做到:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。

查看解题后,发现有一种新的解法:

思路三

摩尔投票

前提是一定有半数以上的值是一样的

设输入数组 nums 的众数为 x ,数组长度为 n 。

  • 推论一: 若记 众数 的票数为 +1,非众数 的票数为 −1,则一定有所有数字的 票数和 >0。
  • 推论二: 若数组的前 a 个数字的 票数和 =0,则 数组剩余 (n−a) 个数字的 票数和一定仍 >0 ,即后 (n−a)个数字的 众数仍为 x。
举个栗子:

[7, 7, 5, 7, 5, 1 | 5, 7 | 5, 5, 7, 7 | 7, 7, 7, 7]
在遍历到数组中的第一个元素以及每个在 | 之后的元素时,candidate 都会因为 count 的值变为 0 而发生改变。最后一次 candidate 的值从 5 变为 7,也就是这个数组中的众数。

假设我们设置出现次数最多的值是moreValue,初始化从0开始,也就是nums[0]假设是我们寻找的结果值

我们维护一个候选众数 moreValue 和正负数相加的值:plusValue。初始时 moreValue 可以为任意值,plusValue 为 0;

我们遍历数组 nums 中的所有元素,对于每个元素 x,在判断 x 之前,如果 plusValue 的值为 0,我们先将 x 的值赋予 moreValue,随后我们判断 x:
如果 x 与 moreValue 相等,那么计数器 plusValue 的值增加 1;
如果 x 与 moreValue 不等,那么计数器 plusValue 的值减少 1。
在遍历完成后,moreValue 即为整个数组的众数。文章来源地址https://www.toymoban.com/news/detail-812598.html

class Solution {
    public int majorityElement(int[] nums) {
        //边界条件
        if(nums == null || nums.length == 0) return 0;
        if(nums.length == 1) return nums[0];

        //假设最多的数值是moreValue
        int moreValue = 0;
        //假设加起来的值是plusValue
        int plusValue = 0;

        for(int i = 0; i < nums.length; i++){
            //如果加起来的值等于0了,新的值作为最多值
            if(plusValue == 0){
                moreValue = nums[i];
            }

            //如果假设的新的值,与新的比较值相等
            if(nums[i] == moreValue){
                //+1
                plusValue++;
            }else{
                //-1
                plusValue--;
            }
        }

        //返回结果
        return moreValue;
    }
}

到了这里,关于剑指 Offer 39.数组中出现次数超过一半的数字的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 剑指 Offer 56 - II. 数组中数字出现的次数 II(位运算 / 哈希表 / 排序)

    链接:剑指 Offer 56 - II. 数组中数字出现的次数 II 难度:中等 在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。 示例 1: 输入:nums = [3,4,3,3] 输出:4 示例 2: 输入:nums = [9,1,7,9,7,9,7] 输出:1 限制: 1 = nums.length = 10000 1

    2024年02月13日
    浏览(30)
  • C++信息学奥赛1186:出现次数超过一半的数

    这段代码的作用是判断给定的整数数组中是否存在出现次数超过一半的元素。首先,通过循环输入整数数组的元素。然后,通过两层循环遍历数组,外层循环逐个元素进行统计,内层循环计算当前元素在数组中出现的次数。在内部循环中,如果发现有元素出现次数超过了数组

    2024年02月10日
    浏览(26)
  • 剑指offer(C++)-JZ56:数组中只出现一次的两个数字(算法-位运算)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 数据范围:数组长度2≤n≤1000,数组中每个数

    2024年02月10日
    浏览(38)
  • 【每日一题】Leetcode - 剑指 Offer 43. 1~n 整数中 1 出现的次数

    Leetcode - 剑指 Offer 43. 1~n 整数中 1 出现的次数 分解数字中的每一位,判断+记录 = 结果 But,超时了,下面是优化过程简介 空间换时间(爆内存) :n = 123456,则n{len-1} = 12345,其实走到n这里,说明n{len-1}这个数字我们一定已经知道了它有多少个1了,所以我们只需要记录保存下

    2024年02月11日
    浏览(38)
  • 每日一题——LeetCode1287.有序数组中出现次数超过25%的元素

    方法一 一次循环统计 题目给出的数据相同的元素都是相邻的,那么直接从头开始遍历,统计每种元素出现次数,当有元素次数超过arr.length/4即为要求的元素   消耗时间和内存情况: 方法二 方法一简化版 设步长step=arr.length/4,如果某个元素arr[i],跨越一个步长后arr[i+step],即

    2024年01月22日
    浏览(41)
  • 【剑指 offer】旋转数组的最小数字

    ✨个人主页:bit me👇 ✨当前专栏:算法训练营👇 核心考点:数组理解,二分查找,临界条件 描述: 有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这

    2023年04月20日
    浏览(43)
  • 【剑指offer】数组中重复的数字

    👑专栏内容:力扣刷题 ⛪个人主页:子夜的星的主页 💕座右铭:前路未远,步履不停 剑指offer:数组中重复的数字 在一个长度为 n 的数组里的所有数字都在 0 0 0 到 n − 1 n-1 n − 1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复,也不知道每个数字重复了几

    2024年01月20日
    浏览(35)
  • 剑指offer03.数组中重复的数字

    看到这道题的第一眼想到的是先给它排序,然后双指针从左往右遍历,写了一个冒泡排序,但是我想到了应该会超时,因为冒泡时间复杂度是n的平方,输入大小时10000,肯定会超时,然后右又看了一下题目看到数字都是0-n-1,灵感一下子就来了,我先创建一个等大的自然数数

    2024年02月11日
    浏览(29)
  • 【剑指offer|1.数组中重复的数字】

    : 长度为n的数组nums中所有数字都在0~n-1范围内 返回任意一个重复的数字 总体时间复杂度和空间复杂度分析: 修改数组的方法: 因为有n个元素,每一个元素都在0~(n-1)范围内,如果元素不重复的话, 对数组重排之后,下标和元素值之间应该是一一对应的关系 但是因为

    2023年04月22日
    浏览(30)
  • 剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 利用题目的限制条件: 所有数字都在 0~n-1 的范围内 通过交互让数字和下标一一对应,如果有多个数字对应同一个下标,那就找到了答案。 另一种写法

    2024年02月11日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包