小学生都能看懂的题解 | #数组中只出现一次的两个数字#

数组中只出现一次的两个数字

https://www.nowcoder.com/practice/389fc1c3d3be4479a154f63f495abff8

问题描述

假设你有一堆小球,这些小球有不同的编号。现在有人告诉你,这堆小球中有两个编号是特殊的,它们只出现了一次,而其他编号的球都出现了两次。你的任务是找出这两个特殊的编号。

解决方案

我们可以用一种巧妙的方法来找出这两个特殊的编号,这种方法叫作“异或操作”。

方法步骤

  1. 计算所有小球编号的异或结果:
  2. 从第一个小球开始,用它的编号作为初始值。
  3. 对每一个小球的编号进行异或操作,即将新编号和当前的异或结果再做一次异或。
  4. 异或操作有一个特性:
  5. 任何数和自己异或等于0,任何数和0异或等于自己。
  6. 这样,那些出现两次的编号就会相互抵消掉,剩下的就是两个特殊编号的异或结果。
  7. 找到特殊编号异或结果中的1:
  8. 异或结果是一个数字,它包含了两个特殊编号的信息。
  9. 我们需要找到这个结果中任何一个位置上的1。
  10. 我们可以用一个简单的技巧来找到这个1的位置:
  11. 将异或结果与其负数相与(xorResult & (-xorResult))。
  12. 根据找到的1来区分两个特殊编号:
  13. 再次遍历所有小球,这次根据找到的1来区分小球:
  14. 如果小球的编号在找到的1的位置上有1,就放到一组。
  15. 如果在找到的1的位置上有0,就放到另一组。
  16. 对这两组小球分别做异或操作,最终得到的就是那两个特殊编号。

示例代码解释

现在我们用简单的语言来解释一下代码:

public class Solution {
    /**
     * 在整型数组中找出两个只出现一次的数字
     * @param nums 输入的整型数组
     * @return 一个包含两个只出现一次的数字的数组,按非降序排列
     */
    public int[] FindNumsAppearOnce(int[] nums) {
        if (nums == null || nums.length < 2) {
            throw new IllegalArgumentException("Invalid input");
        }

        // 第一步:计算所有数字的异或结果
        int xorResult = 0;
        for (int num : nums) {
            xorResult ^= num; // 异或操作
        }

        // 第二步:找到异或结果中任意一个为1的比特位
        int mask = xorResult & (-xorResult); // 找到最低位的1

        // 第三步:根据mask区分两个只出现一次的数字
        int num1 = 0, num2 = 0;
        for (int num : nums) {
            if ((num & mask) != 0) { // 如果在mask的位置上有1
                num1 ^= num; // 放入num1组
            } else {
                num2 ^= num; // 否则放入num2组
            }
        }

        // 按非降序排列结果
        if (num1 < num2) {
            return new int[]{num1, num2};
        } else {
            return new int[]{num2, num1};
        }
    }

}

如果这篇文章对你有帮助,请点个免费的赞👍,让它能够帮助更多的人。

#牛客创作赏金赛#
小学生都能看懂的算法 文章被收录于专栏

主要面向小白的算法文章。以小学生都能看懂为目标而编写,顺便巩固下自己。

全部评论

相关推荐

给🐭🐭个面试机会...:这b打广告打半年了,我真服了,装都不装了现在
点赞 评论 收藏
分享
最近群里有很多同学找我看简历,问问题,主要就是集中在明年三月份的暑期,我暑期还能进大厂嘛?我接下来该怎么做?对于我来说,我对于双非找实习的一个暴论就是title永远大于业务,你在大厂随随便便做点慢SQL治理加个索引,可能就能影响几千人,在小厂你从零到一搭建的系统可能只有几十个人在使用,量级是不一样的。对双非来说,最难的就是约面,怎么才能被大厂约面试?首先这需要一点运气,另外你也需要好的实习带给你的背书。有很多双非的同学在一些外包小厂待了四五个月,这样的产出有什么用呢?工厂的可视化大屏业务很广泛?产出无疑是重要的,但是得当你的实习公司到了一定的档次之后,比如你想走后端,那么中厂后端和大厂测开的选择,你可以选择中厂后端(注意,这里的中厂也得是一些人都知道的,比如哈啰,得物,b站之类,不是说人数超过500就叫中厂),只有这个时候你再去好好关注你的产出,要不就无脑大厂就完了。很多双非同学的误区就在这里,找到一份实习之后,就认为自己达到了阶段性的任务,根本不再投递简历,也不再提升自己,玩了几个月之后,美其名曰沉淀产出,真正的好产出能有多少呢?而实际上双非同学的第一份实习大部分都是工厂外包和政府外包!根本无产出可写😡😡😡!到了最后才发现晚了,所以对双非同学来说,不要放过任何一个从小到中,从中到大的机会,你得先有好的平台与title之后再考虑你的产出!因为那样你才将将能过了HR初筛!我认识一个双非同学,从浪潮到海康,每一段都呆不久,因为他在不断的投递和提升自己,最后去了美团,这才是双非应该做的,而我相信大部分的双非同学,在找到浪潮的那一刻就再也不会看八股,写算法,也不会打开ssob了,这才是你跟别人的差距。
迷茫的大四🐶:我也这样认为,title永远第一,只有名气大,才有人愿意了解你的简历
双非本科求职如何逆袭
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务