leetCode Single Number I II III

本文详细解析了SingleNumber系列算法,包括SingleNumber I、II、III。介绍了如何使用异或操作解决只出现一次的数字问题,并针对不同情况提出了具体解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Single Number系列

Single Number I

Given an array of integers, every element appears twice except for one. Find that single one.

题目描述:

给出一个数组arr,数组中每个元素都仅出现两次,除了其中一个数只出现一次,找出那个数。

思想:

主要的思想是用异或来做,两个相同的数异或后会变为0,所以对数组进行异或,最后得到的结果就是只出现一次的数。

代码:

JAVA AC 时间O(n) 空间O(1)

class Solution {
    public int singleNumber(int[] nums) {
        int len = nums.length;
        if(len<=0) return -1;
        int res = nums[0];
        for(int i=1;i<len;i++){
            res^=nums[i];
        }
        return res;
    }
}

Single Number II

Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

题目描述:

与上题不一样的是,数组中元素每个都出现了3次,除了其中一个数只出现一次,找出这个数。

思想:

考虑全部用二进制表示,如果我们把第i个位置上所有数字的和对3取余,那么只会有两个结果 0 或 1 (根据题意,3个0或3个1相加余数都为0). 因此取余的结果就是那个 “Single Number”。一个直接的实现就是用大小为 32的数组来记录所有位上的和。

代码:

C++ AC 时间O(n) 空间O(1)

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int len = nums.size();
        int res = 0;
        for(int j=0;j<32;j++){
            int sum = 0; //二进制所有数每一位的数字之和
            for(int i=0;i<len;i++){
                 sum+=((nums[i]>>j)&1);
            }
            if(sum%3==1){
                res |=1<<j;
            }
        }
        return res;
    }
};

Single Number III

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

题目描述:

该题目是数组中除了其中2个数只出现一次,其他数都出现了2次,找出这2个数。

思想:

该题目类似于第一题,如果该数组只有一个数出现一次那么可以直接用题目I的逻辑来做

所以我们要对该数组进行分组,把这两个只出现一次的数分别分为A,B两组

那么如何分组呢,首先这两个数肯定是不相同的,那么我们可以把这两个数转化为2进制,进行比较。每一位进行^运算,肯定有其中一位进行^运算后结果为1.

也就是说这两个数在2进制中的这一位,一个是0,一个是1.然后找到这一位的位置,再遍历数组nums,对每个元素的这一位进行^运算,这样通过运算后为0的并入组A,为1的并入组B。

再分别对组A 和 组B进行如题目1的逻辑分别找到对应只出现一次的数。

代码:

C++ AC 时间O(1) 空间O(n)

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        vector<int> res;
        if(nums.size()<=0) return res;
        int res1=0;
        int res2=0;
        int index = findFistSum(nums);
        for(int i=0;i<nums.size();i++){
            if((nums[i]>>index)&1) {res1^=nums[i];}
            else                   {res2^=nums[i];}
        }
        res.push_back(res1);
        res.push_back(res2);
        return res;
    }
    ///返回 二个只有1唯一数异或后 他们的二进制的第一位为1的位置
    int findFistSum(vector<int>& nums){
        //所有数异或
        int res = nums[0];
        for(int i=1;i<nums.size();i++){
            res ^=nums[i];
        }
        for(int i=0;i<32;i++){
            if((res>>i)&1){
                return i;
            }
        }
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值