一.原理
二.例题
1.剑指 Offer II 004. 只出现一次的数字
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
示例 1:
输入:nums = [2,2,3,2]
输出:3
示例 2:
输入:nums = [0,1,0,1,0,1,100]
输出:100
提示:
1 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
进阶:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
解法一:
HashMap
class Solution {
public:
int singleNumber(vector<int>& nums) {
unordered_map<int,int> count;//
for(int element:nums)
count[element]++;
int res=0;
for(auto[num,cnt]:count)
{
if(cnt==1)
{
res=num;
break;
}
}
return res;
}
};
时间复杂度:O(n)
空间复杂度:O(n)
解法二:
二进制取余思想。由于其余数字出现三次,结果数字出现一次。对于结果的二进制每一位符合,对于每i位所有数字的第i位相加后%3是该位的结果。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ans = 0;
for (int i = 0; i < 32; ++i) {
int total = 0;
for (int num: nums) {
total += ((num >> i) & 1);
}
if (total % 3) {
ans |= (1 << i);
}
}
return ans;
}
};
2.剑指 Offer II 010. 和为 k 的子数组
hashmap的空间换时间(循环)
我是不太懂。。。
给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。
示例 1:
输入:nums = [1,1,1], k = 2
输出: 2
解释: 此题 [1,1] 与 [1,1] 为两种不同的情况
示例 2:
输入:nums = [1,2,3], k = 3
输出: 2
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int ans = 0;
unordered_map<int,int> mmap;
int length=nums.size();
mmap[0]=1;
int pre=0;
for(int i=0;i<length;i++)
{
pre+=nums[i];//当前的和
unordered_map<int,int>::iterator it=mmap.find(pre-k);
if(it!=mmap.end())
{
ans+=it->second;
}
mmap[pre]++;
}
return ans;
}
};