当前位置: 首页 > news >正文

【力扣刷题实战】只出现一次的数字III

大家好,我是小卡皮巴拉

文章目录

目录

力扣题目:只出现一次的数字III

题目描述

解题思路

问题理解

算法选择

具体思路

解题要点

完整代码(C++)

兄弟们共勉 !!! 


每篇前言

博客主页:小卡皮巴拉

咱的口号:🌹小比特,大梦想🌹

作者请求:由于博主水平有限,难免会有错误和不准之处,我也非常渴望知道这些错误,恳请大佬们批评斧正。

力扣题目:只出现一次的数字III

原题链接:260. 只出现一次的数字 III - 力扣(LeetCode)

题目描述

给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。

示例 1:

输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。

示例 2:

输入:nums = [-1,0]
输出:[-1,0]

示例 3:

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

解题思路

问题理解

本题要求在给定的整数数组 nums 中找出恰好只出现一次的两个元素,数组里其余元素都出现两次。需要设计一个时间复杂度为线性(O(n))且仅使用常量额外空间(O(1))的算法来解决此问题,最后按任意顺序返回这两个只出现一次的元素。

算法选择

采用位运算的方法。位运算的异或操作能高效地处理元素出现次数的问题,结合异或操作的特性和对结果的进一步处理,可以找出只出现一次的两个元素。

具体思路

  1. 计算所有元素的异或结果

    • 初始化一个变量 xor_all 为 0。

    • 遍历数组 nums,将每个元素 e 与 xor_all 进行异或操作,即 xor_all ^= e。由于相同元素异或结果为 0,所以最终 xor_all 的值是那两个只出现一次的元素的异或结果。

  2. 找出异或结果中某一位为 1 的位

    • 通过 unsigned int diff_bit = static_cast<unsigned int>(xor_all) & static_cast<unsigned int>(-static_cast<unsigned int>(xor_all)); 找出 xor_all 中最右边为 1 的位。这一位为 1 意味着那两个只出现一次的元素在该位上不同。

  3. 根据该位将数组元素分组并分别异或

    • 初始化两个变量 num1 和 num2 为 0。

    • 再次遍历数组 nums,对于每个元素 e,检查其在 diff_bit 位上的值:

      • 如果 e & static_cast<int>(diff_bit) 为真,说明 e 在该位上为 1,将其与 num1 进行异或操作,即 num1 ^= e

      • 否则,说明 e 在该位上为 0,将其与 num2 进行异或操作,即 num2 ^= e

    • 这样分组后,相同的元素会被分到同一组,经过异或操作后会相互抵消,最终 num1 和 num2 分别是那两个只出现一次的元素。

  4. 返回结果

    • 返回包含 num1 和 num2 的向量 {num1, num2}

解题要点

  1. 异或操作的特性运用:利用异或操作 a ^ a = 0 和 a ^ 0 = a 的特性,通过对所有元素异或得到两个只出现一次元素的异或结果。

  2. 找出不同位:通过 xor_all 与 -xor_all 进行按位与操作,找出两个只出现一次元素不同的某一位,以此作为分组的依据。

  3. 分组异或:根据找出的不同位将数组元素分组并分别异或,最终得到两个只出现一次的元素。

完整代码(C++)

class Solution {
public:
    std::vector<int> singleNumber(std::vector<int>& nums) 
    {
        int xor_all = 0;
        // 遍历数组,将所有元素进行异或操作,得到两个只出现一次元素的异或结果
        for(auto e : nums)
        {
            xor_all ^= e;
        }
        // 找出 xor_all 中最右边为 1 的位,该位表明两个只出现一次的元素在该位不同
        unsigned int diff_bit = static_cast<unsigned int>(xor_all) & 
                                static_cast<unsigned int>(-static_cast<unsigned int>(xor_all));

        int num1 = 0, num2 = 0;
        // 根据 diff_bit 位将数组元素分组并分别异或
        for(auto e : nums)
        {
            if(e & static_cast<int>(diff_bit)) num1 ^= e;
            else num2 ^= e;
        }
        return {num1, num2};
    }
};

兄弟们共勉 !!! 

码字不易,求个三连

抱拳了兄弟们!

相关文章:

  • CVPR2025 | 蚂蚁浙大提出MP-GUI算法:全方位增强MLLM的GUI理解能力
  • VLAN的处理机制
  • 爬虫——playwright获取亚马逊数据
  • Web爬虫利器FireCrawl:全方位助力AI训练与高效数据抓取
  • 服务器部署Kong和Konga过程
  • vue路由去掉#
  • 07. 面向对象高级(2)_设计模式
  • 基于ssm的在线点歌系统(全套)
  • 电源电路篇
  • python:AI+ music21 构建LSTM模型生成爵士风格音乐
  • Liunx安装elasaticsearch、ik分词器、kibana
  • 批处理文件:用gifsicle删除gif文件中的奇数帧
  • 【快递分拣员-Git介绍】
  • elsticsearch 通过reindex修改shards
  • 使用crash解析vmcore(fulldump)文件,基于qemu,arm64,linux6.6
  • 社区医疗管理系统基于Spring Boot SSM
  • Trae如何使用插件Mybatis Log MybatisX转换SQL语句?
  • 分裂层次聚类算法:从原理到实战的全方位解析
  • Java-模块一
  • Controller/RestController的区别
  • “走进书适圈”:一周城市生活
  • 媒体:“重病老人银行取款身亡”涉事家属称已和解,银行将支付十万
  • 艺术稀缺性和价值坚守如何构筑品牌差异化壁垒?从“心邸”看CINDY CHAO的破局之道
  • 日本一季度实际GDP环比下降0.2%
  • 华东政法与复旦上医签署合作框架协议,医学与法学如何交叉融合?
  • 泽连斯基:正在等待俄方确认参加会谈的代表团组成