目录
- 1. 只出现一次的数字 I
- 2. 只出现一次的数字 II
1. 只出现一次的数字 I
题目描述:给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。你必须设计并实现线性时间复杂度(O(n))的算法来解决此问题,且该算法只使用常量额外空间(O(1))。
示例 1 :
输入:nums = [2,2,1]
输出:1
示例 2 :
输入:nums = [4,1,2,1,2]
输出:4
示例 3 :
输入:nums = [1]
输出:1
提示:
1 <= nums.length <= 3 * 104
-3 * 104 <= nums[i] <= 3 * 104
除了某个元素只出现一次以外,其余每个元素均出现两次。
题目链接:https://leetcode.cn/problems/single-number/description/?clienttype=8&version=7.40.0.113&from=win32_yunguanjia&channel=00000000000000000000000040000001&privilege=&pri_extra=
答:解题思路:非空数组中除一个元素出现一次外,其余元素均出现两次。由于相同的数异或为0,而其他数与0异或不变。所以,遍历数组把所有数异或一遍,出现两次的数都异或为0了,则结果为只出现一次的元素。
代码如下: 由于作者最近在学习STL,所以代码中使用的都是迭代器,大家看不习惯可以点击链接看别的代码。
class Solution {
public:int singleNumber(vector<int>& nums) {// 所需变量int key = 0; // 存储只出现一次的数// 使用迭代器遍历数组,每个元素相互亦或vector<int>::iterator begin = nums.begin();vector<int>::iterator end = nums.end();while (begin != end){// 当前元素亦或key ^= *begin;// 下一个元素++begin;}// 输出return key;}
};
2. 只出现一次的数字 II
题目描述:给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。你必须设计并实现线性时间复杂度的算法(O(n))且使用常数级空间(O(1))来解决此问题。
示例 1:
输入:nums = [2,2,3,2]
输出:3
示例 2:
输入:nums = [0,1,0,1,0,1,99]
输出:99
提示:
1 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
题目链接: https://leetcode.cn/problems/single-number-ii/?clienttype=8&version=7.40.0.113&from=win32_yunguanjia&channel=00000000000000000000000040000001&privilege=&pri_extra=
答:解题思路:首先,数组的类型为int,所以每个数有32位,而其他数都是3对出现的,所以32位中,为1的位的次数要么是3n,要么是3n+1,而出现次数为3n+1则是所求只出现1次的数的为1位,出现次数为3n则是所求只出现1次的数的为0位。然后,通过与1异或还原为1的位。
代码如下:
class Solution {
public:int singleNumber(vector<int>& nums) {// 创建一个包含32个元素的int数组,遍历数组存储32位数中每位上1的出现次数int times_per_bit[32] = { 0 };int size = nums.size();for (int i = 0; i < size; ++i){// 存储每位数1出现的次数for (int j = 0; j < 32; ++j){// 判断本位是否为1if (nums[i] & (1 << j)){// 次数加1++times_per_bit[j];}}}// 遍历每位为1的次数数组,出现次数不是3n的倍数的位,为所求元素为1的位int key = 0;for (int i = 31; i >= 0; --i){// 还原所求值if (times_per_bit[i] % 3)key = key ^ (1 << i);}return key;}
};