class Solution {
public:
bool isAnagram(string s, string t) {
int arr[26]={0};
for(int i=0;i<s.size();++i)
{
++arr[s[i]-'a'];
}
for(int j=0;j<t.size();++j)
{
--arr[t[j]-'a'];
}
for(int i=0;i<26;++i)
{
if(arr[i]) return false;
}
return true;
}
};
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
vector<int> tmp;
std::unordered_set<int> s(nums1.begin(),nums1.end());
std::unordered_set<int> t(nums2.begin(),nums2.end());
for(auto it:t)
{
auto iter = s.find(it);
if(iter!=s.end())
{
tmp.emplace_back(it);
}
}
return tmp;
}
};
//这样也可以
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重
unordered_set<int> nums_set(nums1.begin(), nums1.end());
for (int num : nums2) {
// 发现nums2的元素 在nums_set里又出现过
if (nums_set.find(num) != nums_set.end()) {
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
class Solution {
public:
bool isHappy(int n) {
std::unordered_set<int> res;
while(1)
{
int sum=0;
while(n)
{
int a=n%10;
sum += a*a;
n /=10;
}
if(sum == 1) return true;
auto iter=res.find(sum);
if(iter!=res.end()){
break;
}else
{
res.emplace(sum);
}
n=sum;
}
return false;
}
};
递归法:
class Solution {
public:
bool isHappy(int n) {
std::unordered_set<int> res;
return happy(res,n);
}
private:
bool happy(unordered_set<int>& res,int n)
{
int sum=0;
while(n)
{
sum += (n%10)*(n%10);
n /= 10;
}
//算完的结果判断是否为快乐树
if(sum == 1) return true;
//不是快乐树在考虑是否存在set中,判断是否要退出
if(res.find(sum)!=res.end()) return false;
//res.count(sum)
res.emplace(sum);
return happy(res,sum);
}
};
vector<int> twoSum(vector<int>& nums, int target) {
std::unordered_map<int,int> res;
for (int i=0;i<nums.size();++i){
auto iter = res.find(target-nums[i]);
if(iter!=res.end()) return {iter->second,i};
res.emplace(nums[i],i);
}
return {};
}
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
std::unordered_map<int,int> res;
int count = 0;
for(int i=0;i<nums1.size();++i)
{
for(int j=0;j<nums2.size();++j)
{
++res[nums1[i]+nums2[j]];
}
}
for(int k=0;k<nums3.size();++k)
{
for(int l=0;l<nums4.size();++l)
{
int val = -(nums3[k]+nums4[l]);
if (res.count(val)){
count += res[val];
}
}
}
return count;
}
};
//随想录版
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
unordered_map<int, int> umap; //key:a+b的数值,value:a+b数值出现的次数
// 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中
for (int a : A) {
for (int b : B) {
umap[a + b]++;
}
}
int count = 0; // 统计a+b+c+d = 0 出现的次数
// 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来。
for (int c : C) {
for (int d : D) {
if (umap.find(0 - (c + d)) != umap.end()) {
count += umap[0 - (c + d)];
}
}
}
return count;
}
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int arr[26]={0};
for(int i=0;i<magazine.size();++i)
{
++arr[magazine[i]-'a'];
}
for(int j=0;j<ransomNote.size();++j)
{
if(--arr[ransomNote[j]-'a']<0) return false;
}
return true;
}
};
//随想录版
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int record[26] = {0};
//add
if (ransomNote.size() > magazine.size()) {
return false;
}
for (int i = 0; i < magazine.length(); i++) {
// 通过recode数据记录 magazine里各个字符出现次数
record[magazine[i]-'a'] ++;
}
for (int j = 0; j < ransomNote.length(); j++) {
// 遍历ransomNote,在record里对应的字符个数做--操作
record[ransomNote[j]-'a']--;
// 如果小于零说明ransomNote里出现的字符,magazine没有
if(record[ransomNote[j]-'a'] < 0) {
return false;
}
}
return true;
}
};
这题主要是考虑如何去重,以及哈希法是否适应(事实上去重不方便),多做几次熟悉该类题的思想
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
// 找出a + b + c = 0
// a = nums[i], b = nums[left], c = nums[right]
for (int i = 0; i < nums.size(); i++) {
// 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
if (nums[i] > 0) {
return result;
}
// 错误去重a方法,将会漏掉-1,-1,2 这种情况
/*
if (nums[i] == nums[i + 1]) {
continue;
}
*/
// 正确去重a方法
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1;
int right = nums.size() - 1;
while (right > left) {
// 去重复逻辑如果放在这里,0,0,0 的情况,可能直接导致 right<=left 了,从而漏掉了 0,0,0 这种三元组
/*
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
*/
if (nums[i] + nums[left] + nums[right] > 0) right--;
else if (nums[i] + nums[left] + nums[right] < 0) left++;
else {
result.push_back(vector<int>{nums[i], nums[left], nums[right]});
// 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
// 找到答案时,双指针同时收缩
right--;
left++;
}
}
}
return result;
}
};
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
//排序
int n = nums.size();
sort(nums.begin(),nums.end());
vector<vector<int>> res;
for(int i=0;i<n;++i)
{
if(i>0&&nums[i]==nums[i-1]) continue;
for(int j=i+1;j<n;++j)
{
if(j>i+1&&nums[j]==nums[j-1]) continue;
int left = j+1;
int right = n-1;
while(left<right)
{
//long保证相加结果不会溢出
if((long)nums[j]+nums[left]+nums[right]<target-nums[i])
{
++left;
}else if((long)nums[j]+nums[left]+nums[right]>target-nums[i])
{
right--;
}else{
res.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]});
while(left<right&&nums[left]==nums[left+1]) ++left;
while(left<right&&nums[right]==nums[right-1]) --right;
++left;
--right;
}
}
}
}
return res;
}
};
优化:(重点是两个优化的操作)
vector<vector<int>> fourSum(vector<int>& nums, int target) {
//排序
int n = nums.size();
sort(nums.begin(),nums.end());
vector<vector<int>> res;
for(int i=0;i<n;++i)
{
if(nums[i]>target&&nums[i]>=0) break;//减枝
if(i>0&&nums[i]==nums[i-1]) continue;//去重
for(int j=i+1;j<n;++j)
{
if(nums[i]+nums[j]>target&&nums[i]+nums[j]>=0) break;//减枝
//优化if(nums[i]+nums[j]>target&&nums[j]>=0);
if(j>i+1&&nums[j]==nums[j-1]) continue;
int left = j+1;
int right = n-1;
while(left<right)
{
if((long)nums[j]+nums[left]+nums[right]<target-nums[i])
{
++left;
}else if((long)nums[j]+nums[left]+nums[right]>target-nums[i])
{
right--;
}else{
res.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]});
while(left<right&&nums[left]==nums[left+1]) ++left;
while(left<right&&nums[right]==nums[right-1]) --right;
++left;
--right;
}
}
}
}
return res;
}