题⽬描述

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

思路及解答

哈希表法(HashMap)

哈希表法通过统计每个数字的出现次数来解决问题。遍历数组时,使用哈希表记录每个数字出现的次数,一旦发现某个数字的出现次数超过数组长度的一半,立即返回该数字。

public class Solution {
public int MoreThanHalfNum(int[] nums) {
// 创建哈希表,key为数字,value为出现次数
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
// 获取当前数字的出现次数并加1,若不存在则初始化为0再加1
int count = map.getOrDefault(num, 0) + 1;
// 若当前数字出现次数已超过数组长度一半,则返回该数字
if (count > nums.length / 2) {
return num;
}
map.put(num, count); // 更新哈希表
}
return 0; // 如果不存在多数元素,返回0(但题目假设总是存在)
}
}
  • 时间复杂度​:O(n),其中 n 是数组的长度。我们只需遍历数组一次。
  • 空间复杂度​:O(n),最坏情况下需要存储所有不同的数字。

排序法

排序法的思路非常巧妙:​由于多数元素的数量超过数组长度的一半,那么将数组排序后,中间位置的元素一定是多数元素。

public class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums); // 对数组进行排序
return nums[nums.length / 2]; // 返回中间位置的元素
}
}

摩尔投票法(Boyer-Moore Voting Algorithm)

  1. 如果使⽤ hashmap 直接统计,需要额外的空间,我们不希望使⽤额外空间;
  2. 如果使⽤排序之后再统计,需要时间复杂度为O(nlogn), 我们希望时间复杂度更低⼀点。

摩尔投票法是一种高效且空间复杂度低的算法。其核心思想是通过票数的抵消来找出多数元素。算法维护一个候选众数 candidate 和其票数 count。遍历数组时,若 count 为0,则选择当前数字作为候选;若当前数字与候选相同,则票数加1,否则减1。由于多数元素的存在,最终剩下的候选一定是多数元素。

public class Solution {
public int majorityElement(int[] nums) {
int candidate = 0; // 候选众数
int count = 0; // 票数统计 for (int num : nums) {
if (count == 0) { // 如果票数为0,选择当前数字作为候选
candidate = num;
}
// 如果当前数字与候选相同,则票数加1,否则减1
count += (num == candidate) ? 1 : -1;
} // 可选:验证candidate是否真的是多数元素(根据题目假设,通常不需要)
// 但如果题目要求不存在多数元素时返回0,则需要验证步骤
count = 0;
for (int num : nums) {
if (num == candidate) count++;
} return count > nums.length / 2 ? candidate : 0;
}
}
  • 时间复杂度​:O(n),只需遍历数组两次(一次投票,一次验证)。
  • 空间复杂度​:O(1),只使用了常数个额外变量

剑指offer-28、数组中出现次数超过⼀半的数字的更多相关文章

  1. 剑指Offer 28. 数组中出现次数超过一半的数字 (数组)

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  2. 《剑指offer》数组中出现次数超过数组长度一半的数字

    题目: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如 ...

  3. 【剑指offer】数组中出现次数超过数组长度一半的数字,C++实现

    原创博文,转载请注明出处! # 题目 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过 ...

  4. [剑指Offer] 28.数组中出现次数超过一半的数字

    [思路]将每个数字都存入map中作为key值,将它们出现的次数作为value值,当value超过一半时则返回其key值. class Solution { public: int MoreThanHa ...

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

    剑指Offer:数组中出现次数超过一半的数字[39] 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于这 ...

  6. 剑指 Offer 39. 数组中出现次数超过一半的数字 + 摩尔投票法

    剑指 Offer 39. 数组中出现次数超过一半的数字 Offer_39 题目描述 方法一:使用map存储数字出现的次数 public class Offer_39 { public int majo ...

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

    剑指 Offer 39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [ ...

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

    题目 剑指 Offer 39. 数组中出现次数超过一半的数字 思路1(排序) 因为题目说一定会存在超过数组长度一半的一个数字,所以我们将数组排序后,位于length/2位置的一定是众数 代码 clas ...

  9. 【剑指Offer】数组中出现次数超过一半的数字 解题报告(Python)

    [剑指Offer]数组中出现次数超过一半的数字 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-inter ...

  10. 《剑指offer》数组中只出现一次的数字

    本题来自<剑指offer> 数组中只出现一次的数字 题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: 思路一:在<剑指of ...

随机推荐

  1. Java开发AI项目,太爽了!LangChain4j保姆级教程

    大家好,我是程序员鱼皮.现在 AI 应用开发可以说是程序员必备的技能了,求职时能够大幅增加竞争力.之前我用 Spring AI 带大家做过一个 开源的 AI 超级智能体项目,这次我来带大家快速掌握另一 ...

  2. LINUX中防护墙放行端口--九五小庞

    1.查看开放的端口firewall-cmd --list-ports 2.防护墙放行3306端口firewall-cmd --zone=public --add-port=3306/tcp --per ...

  3. git使用每次输入密码问题

    原因:在初始化配置Git用户信息时,设置了用户密码 解决方式:重置用户密码,并设置为空 $ ssh-keygen -p Enter file in which the key is (/c/Users ...

  4. CVE-2020-17526 Apache Airflow 身份验证绕过漏洞 (复现)

    开启容器前执行docker compose run airflow-init初始化Apache Airflow 数据库 再执行docker compose up -d开启容器 访问ip:8080端口登 ...

  5. U559662 不一般的操作-区间dp

    U559662 不一般的操作 解析 对于操作次数只有 \(0\) 次的答案,直接判断 \(p\) 数组是否是 \(1\) 到 \(n\) 即可. 对于操作次数只有 \(1\) 次的答案,枚举断点 \( ...

  6. git拉取远程指定分支到本地

    git拉取远程指定分支到本地 以前写自己模块的时候,曾经建了一个本地分支dev,然后这个分支很久没有使用了,最近又要使用这个分支dev,然后要将远程仓库master分支上的内容同步到我本地dev分支 ...

  7. 知识库与AI:程序员的进阶之路

    在快速发展的IT行业,程序员需要不断学习和更新知识.构建和利用知识库,并结合人工智能(AI)技术,是提升程序员竞争力的关键.本文将探讨如何有效地利用知识库和学习资源,并结合AI来加速学习和解决问题. ...

  8. Dubbo系列之常用配置用法简介

    Dubbo系列之常用配置用法简介 1.配置原则 配置原则,引用官方的图片: JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口. XML 次之,如果在 ...

  9. axios 的二次封装及使用

    1 // 将axios再次封装 2 import axios from 'axios'; // npm i -S axios 3 4 import Qs from 'qs' // npm i -S q ...

  10. F - A Very Easy Graph Problem HDU - 6832 未解决

    An undirected connected graph has $n$ nodes and $m$ edges, The $i$-th edge's length is $2^i$. Each n ...