LeetCode.只出现一次的数 I 、II 、 III

只出现一次的数,三种题型

1.只出现一次的数I

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

示例 2:

输入: [4,1,2,1,2]
输出: 4

这道题很简单,将数组中所有的数字挨个抑或就行,因为两个相同的数字抑或为0,0抑或任何数就是任何数,抑或完所有的数字后,剩下的就是那个单独出现的数字

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int res = 0;
        for (const auto&e : nums)
        {
            res ^= e;
        }
        
        return res;
    }
};

2.只出现一次的数II

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,3,2]
输出: 3

示例 2:

输入: [0,1,0,1,0,1,99]
输出: 99

这道题,刚开始有点不好想,不妨我们直接调用库函数sort来将这个数组进行排序,之后遍历这个数组,如果当前nums[i] == nums[i+1]直接让i += 3跳过这个数字,直到当前两个数字不相等返回下标为i的数字就行。

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        if (nums.empty())
            return 0;
        
        
        sort(nums.begin(), nums.end());
        size_t i = 0;
        while (i < nums.size() - 1)
        {
            if (nums[i] == nums[i + 1])
            {
                i += 3;
            }
            else
                break;
        }
        
        return nums[i];
    }
};

3. 只出现一次的数字III

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。

示例 :

输入: [1,2,1,3,2,5]
输出: [3,5]

这道题,乍一看有点懵逼。但是这道题主要体现的是一个分组的思想。

我们先将数组的数全部抑或一遍,那么剩下的数字就是那两个只出现一次的数字的抑或后的结果。

根据抑或的规则,相同为0,相反为1。那么就很容易了,我们需要先找到这个数字的二进制第一个为1的位。那么就说明,这两个数字的这一位一个为1,一个为0。然后再进行遍历数组,将数组根据条件分为两组分别再进行抑或。

怎么分呢?

如果当前数组的这一位(就是刚才找出的那个比特位)为1分为一组,为0分为一组。然后分别抑或这两组。会得到那两个只出现一次的数组。

class Solution {
public:
	vector<int> singleNumber(vector<int>& nums) {
		

		int ans = 0;
		size_t begin = 0;

		while (begin < nums.size())
		{
			ans ^= nums[begin];

			begin++;
		}

		//找二进制第一个为1的位
		int bit = 1;
		while (1)
		{
			if ((bit & ans) != 0)
				break;

			bit <<= 1;
		}

		begin = 0;
		int res1 = 0;
		int res2 = 0;
		
        //分组抑或
		while (begin < nums.size())
		{
			if ((nums[begin] & bit) != 0)
			{
				res1 ^= nums[begin];
			}
			else
			{
				res2 ^= nums[begin];
			}

			begin++;
		}

		vector<int> rev;
		rev.push_back(res1);
		rev.push_back(res2);

		return rev;
	}
};

猜你喜欢

转载自blog.csdn.net/weixin_42678507/article/details/88896785