137. 只出现一次的数字 IIhttps://leetcode.cn/problems/single-number-ii/
给你一个整数数组 nums
,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。
示例 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
中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
思路一:
1、判断边界条件:一种是nums的大小为1,那答案ans就是nums[0];
另一种是判断ans是否位于数组nums的首尾位置。
2、ans不符合上述情况时,ans就只能在nums中间某位置,遍历nums数组,如果遇到三个相邻的不同的数,则ans就是三个数中间的那个数
示例:nums:111222……555 6 777…… 很明显,567中,6就是ans值
复杂度
时间复杂度:O(n)
空间复杂度:O(1)
Code-1
C++
class Solution {
public:
int singleNumber(vector<int>& nums) {
int n=nums.size();
if(n==1) return nums[0];
sort(nums.begin(),nums.end());//从小到大排序
if(nums[0]!=nums[1]) return nums[0];//首位置
if(nums[n-1]!=nums[n-2]) return nums[n-1];//末位置
int ans;
for(int i=1;i<n-1;i++) //找出连续三个都不同的数
if(nums[i]!=nums[i-1]&&nums[i]!=nums[i+1]) return nums[i];
return 0;
}
};
思路二
1、利用map容器记录每种数字出现的次数,为了减少时间成本,可以采用无须排序的unordered_map容器进行存储。
2、对数组进行遍历,统计每种数字的个数,循环判断哪个数字的个数为1,直接返回即可。
Code-2
C++
class Solution {
public:
int singleNumber(vector<int>& nums) {
unordered_map<int,int> m;
for(auto x:nums) m[x]++;
for(auto [a,b]:m){
if(b==1) return a;
}
return 0;
}
};