游乐游手机版
首页/AI教程/文章详情

数组其他数偶数次找出现奇数次的数Java进阶

时间:2026-06-19 14:40
给定整型数组,一个数出现奇数次时,遍历数组做异或运算即可得到该数;若两个数出现奇数次,先整体异或得到两数异或值,再根据某一位为1将数组分为两组分别异或,得到两个奇数次数。时间复杂度O(N),额外空间O(1)。

在算法面试与编程挑战中,有一道极为经典的题目经常出现:给定一个整数数组,其中只有一个数字出现了奇数次,其余数字均出现偶数次,要求找出这个出现奇数次的数。进一步升级的问题是,如果数组中有两个数字出现了奇数次,其他数字都是偶数次,又该如何求解?两个问题均设定了严格的时间与空间限制——必须满足时间复杂度 O(N),额外空间复杂度 O(1)。

题目

给定一个整型数组 arr,其中只有一个元素出现了奇数次,其余元素均出现偶数次,请输出这个出现奇数次的数。

进阶

有两个数出现奇数次,其他所有数均出现偶数次,需要输出这两个出现奇数次的数。

难度与要求

本题难度为中等。要求时间复杂度 O(N),额外空间复杂度 O(1)。

解答

首先需要明确异或运算的一个基本性质:任何整数 n 与 0 进行异或(XOR)运算的结果为 n,而 n 与自身异或的结果为 0。此外,异或运算满足交换律和结合律。基于这些特性,我们可以设计出极其简洁的解法。

对于只有一个数出现奇数次的场景,先声明一个整型变量 eO,并初始化为 0。然后遍历整个数组,让 eO 与每个数执行异或操作(eO = eO ^ 当前数)。遍历结束后,eO 的值就是那个出现奇数次的数。为什么这种方法有效?因为异或运算满足交换律和结合律,数组中所有出现偶数次的数在异或过程中会成对抵消为 0,最终只留下出现奇数次的数。举例说明:假设 A、B、C 各出现偶数次,D 出现奇数次,无论以何种顺序进行异或,结果都等同于先连续异或所有 A,再连续异或所有 B,依此类推,最后异或 D。偶数次的数抵消后结果为 0,最终结果就是 D。因此,只要数组中仅有一个数出现奇数次,无论元素顺序如何,最终的 eO 就是该数。对应的实现方法可参考 printOddTimesNum1。

对于有两个数出现奇数次的场景,设这两个数分别为 a 和 b。第一轮遍历后,eO 的值等于 a ^ b,且该结果一定不为 0。由于 eO 非零,其 32 位二进制表示中至少有一位是 1。假设第 k 位为 1,这意味着 a 和 b 在第 k 位上一个为 1、另一个为 0。接下来再设置一个变量 eOhasOne 并初始化为 0,进行第二次遍历。在第二次遍历中,只对第 k 位为 1 的数进行异或,忽略第 k 位为 0 的数。这样,第二次遍历结束后,eOhasOne 就是 a 或 b 中的某一个,而 eO ^ eOhasOne 的结果即为另一个出现奇数次的数。该思路的核心在于利用某一位的差异将两个数划分到不同的子集中,再分别进行异或操作。

package live.every.day.ProgrammingDesign.CodingInterviewGuide.BitwiseOperation;

/**
 * 在其他数都出现偶数次的数组中找到出现奇数次的数
 *
 * 进阶版:找到两个出现奇数次的数
 */
public class InOtherNumAppearEvenArrayFindAppearOddNum2 {

    public static void printOddTimesNum2(int[] arr) {
        int eO = 0, eOhasOne = 0;
        for (int curNum : arr) {
            eO ^= curNum;
        }
        int rightOne = eO & (~eO + 1);
        for (int cur : arr) {
            if ((cur & rightOne) != 0) {
                eOhasOne ^= cur;
            }
        }
        System.out.println(eOhasOne + " " + (eO ^ eOhasOne));
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 3, 2, 8, 1, 6};
        printOddTimesNum2(arr);
    }
}
// ------ Output ------
/*6 8*/

整体思路非常清晰:首先利用异或运算的交换律和结合律消除所有出现偶数次的数,再通过定位二进制位上的差异来分离两个出现奇数次的数。代码实现简洁高效,是位运算在实际问题中的经典应用案例。

来源:https://blog.csdn.net/chimomo/article/details/129916402
上一篇如何用DeepSeek+Kimi打造高分PPT全网最详细教程与AI工具进阶指南 下一篇AI绘画必备资源分类精选整理合集推荐收藏
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Windows Docker Desktop RabbitMQ生产级部署完整指南
AI教程 · 2026-06-29

Windows Docker Desktop RabbitMQ生产级部署完整指南

前言 在 Windows 本地开发环境中,直接安装 RabbitMQ 确实颇为周折:需要单独配置 Erlang 运行环境、手动管理环境变量、服务启停全凭手工操作。更令人困扰的是,版本兼容冲突、端口占用、环境不一致等问题层出不穷。笔者见过不少开发者为搭建环境就得耗费整整半天时间。 相比之下,借助 Do

AI搜索重构制造业采购逻辑的阿里云企业级GEOCMS优化实践
AI教程 · 2026-06-29

AI搜索重构制造业采购逻辑的阿里云企业级GEOCMS优化实践

先分享一个切实感受。过去两年,我们与福建制造企业合作较为频繁,发现一个非常突出的现象:超过80%的企业官网,产品参数仍然存放在PDF或图片中。AI爬虫?根本无法抓取。这些企业技术实力不弱、资质证照齐全、应用案例也丰富,但在AI搜索这一全新战场上,它们几乎处于隐身状态。 一、一个正在发生的行业变化 A

阿里云Token Plan团队版功能价格与省钱购买指南
AI教程 · 2026-06-29

阿里云Token Plan团队版功能价格与省钱购买指南

阿里云百炼近期推出了名为“Token Plan 团队版”的全新服务,这一服务专为企业与开发者量身打造,定位为AI大模型订阅平台。通过引入Credits作为统一计量单位,将文本生成、图像生成等多模态AI能力纳入单一计费体系,同时无缝兼容主流AI编程工具及智能体(Agent)生态系统。其核心亮点包括:全

阿里云物联网.NET Core客户端位置信息上报
AI教程 · 2026-06-29

阿里云物联网.NET Core客户端位置信息上报

阿里云物联网平台的位置服务并非一个完全独立的功能模块。位置信息可包含二维坐标与三维坐标,而位置数据的来源本质上是借助设备属性进行上传。换言之,若要让设备上报位置,您需先将其视为一个普通属性进行处理。 1)添加二维位置数据 操作过程十分简洁。进入数据分析 → 空间数据可视化 → 二维数据,点击添加,将

年阿里云服务器选型配置与网站部署全攻略
AI教程 · 2026-06-29

年阿里云服务器选型配置与网站部署全攻略

2026年,阿里云服务器生态已高度成熟,形成了清晰的轻量应用服务器与ECS云服务器两大产品阵营。无论你是计划搭建个人博客、企业官网,还是运营电商平台、进行应用开发,基本都能找到理想的解决方案。本指南将从服务器选型、配置选择、部署流程到安全运维,系统梳理2026年最实用的操作要点,帮助你少走弯路,让网