剑指 Offer(第2版)面试题 56:数组中数字出现的次数

剑指 Offer(第2版)面试题 56:数组中数字出现的次数

  • 剑指 Offer(第2版)面试题 56:数组中数字出现的次数
    • 题目一:数组中只出现一次的两个数字
    • 题目二:数组中唯一只出现一次的数字

剑指 Offer(第2版)面试题 56:数组中数字出现的次数

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

题目描述:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。你可以假设这两个数字一定存在。

要求时间复杂度是 O(n),空间复杂度是 O(1)。

算法:

  1. 设 num1 和 num2 是数组中只出现一次的两个数字,对数组 nums 求异或和 numsXor,numsXor = num1 ^ num2。
  2. 因为 num1 和 num2 不一样,所以它们异或的结果不为 0。求 numsXor 的最低位的第一个 1,记为 indexOf1。我们以第 indexOf1 位是不是 1 为标准把原数组的数字分成两个子数组,第一个子数组中每个数字的第 indexOf1 位都是 1,而第二个子数组中每个数字的第 indexOf1 位都是 0。
  3. 按这样的标准分配,出现了两次的数字一定分配到同一个数组里,而 num1 和 num2 一定分配到不同的数组里,问题转换为在数组中找到唯一一个出现一次的数字。

解法:Leetcode136. 只出现一次的数字

代码:

class Solution
{
public:
	vector<int> findNumsAppearOnce(vector<int> &nums)
	{
		if (nums.size() < 2)
			return {};
		int numsXor = 0;
		for (int &num : nums)
			numsXor ^= num;
		unsigned int indexOf1 = FindFirstBit1(numsXor);
		int num1 = 0, num2 = 0;
		for (int &num : nums)
		{
			if (isBit1(num, indexOf1))
				num1 ^= num;
			else
				num2 ^= num;
		}
		return {num1, num2};
	}
	// 辅函数 - 求出数 x 的最低位的 1 的位数
	unsigned int FindFirstBit1(int x)
	{
		int index = 0;
		while (((x & 1) == 0) && index < 8 * sizeof(int))
		{
			x >>= 1;
			index++;
		}
		return index;
	}
	// 辅函数 - 判断数 x 的第 indexBit 位是不是 1
	bool isBit1(int x, unsigned int indexBit)
	{
		x >>= indexBit;
		return x & 01;
	}
};

复杂度分析:

时间复杂度:O(n),其中 n 是数组 nums 的元素个数。

空间复杂度:O(1)。

题目二:数组中唯一只出现一次的数字

题目来源:AcWing 74. 数组中唯一只出现一次的数字

题目描述:在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。你可以假设满足条件的数字一定存在。

要求只使用 O(n) 的时间和额外 O(1) 的空间。

我们把数组中的所有数字的二进制表示的每一位都加起来。如果某一位的和能被 3 整除,那么那个只出现一次的数字二进制中对应的那一位是 0,否则是 1。

代码:

class Solution
{
private:
	const int BITS = 32;

public:
	int findNumberAppearingOnce(vector<int> &nums)
	{
		int ans = 0;
		for (int i = 0; i < BITS; i++)
		{
			int cnt1 = 0;
			for (int &num : nums)
				cnt1 += (num >> i) & 01;
			if (cnt1 % 3 == 1)
				ans |= 1 << i;
		}
		return ans;
	}
};

复杂度分析:

时间复杂度:O(BITS * n),其中 BITS = 32,是 int 类型的位数,n 是数组 nums 的元素个数。

空间复杂度:O(1)。

你可能感兴趣的:(剑指,Offer,C++,剑指Offer,位运算,数据结构与算法)