力扣242有效的字母异位词
class Solution {
public:
bool isAnagram(string s, string t) {
vector<int>hash(26,0);
for(int i=0;i<s.length();i++){
hash[s[i]-'a']++;
}
for(int i=0;i<t.length();i++){
hash[t[i]-'a']--;
}
for(int i=0;i<26;i++){
if(hash[i]!=0) return false;
}
return true;
}
};
力扣349两个数组的交集
本题使用set解决,set分为三种
set,multiset是基于红黑树实现
unorderset是基于哈希映射实现(默认去重)
class Solution {
public:
//如果数的范围大的或者数比较分散,用数组不合适,因为有大量的空闲位置,应该用set
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
//result存储结果
unordered_set<int> result;
//nums1_set存放nums1
unordered_set<int> nums1_set(nums1.begin(),nums1.end());
//遍历nums2 并尝试在nums1_set中寻找
for(int i=0;i<nums2.size();i++){
//找到了,就放进result
if(nums1_set.find(nums2[i])!=nums1_set.end()){
result.insert(nums2[i]);
}
}
//因为题目要求返回vector
vector<int> res(result.begin(),result.end());
return res;
}
};
力扣1两数之和
class Solution {
public:
//这道题的哈希表除了存值,还得存下标,只能用map
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
//为啥用元素值做key而不是用map做key?因为find是找key
//将nums这个vector数组存进num这个map数组
map<int,int> num;
for(int i=0;i<nums.size();i++){
num.insert(make_pair (nums[i], i));//插入键值对
}
for(int i=0;i<nums.size();i++){
if(num.find(target-nums[i])!=num.end()&&i!=num[target-nums[i]]){
res.push_back(i);
res.push_back(num[target-nums[i]]);
break;//找到一对
}
}
return res;
}
};
力扣202快乐数
class Solution {
public:
//统计每个位置上的数字的平方和
int getSum(int n){
int res=0;
while(n){
res+=(n%10)*(n%10);
n/=10;
}
return res;
}
bool isHappy(int n) {
unordered_set<int> hash;//判断sum是否重复出现就可以使用unordered_set
while(n!=1){
hash.insert(n);
n=getSum(n);//每一次将该数替换为它每个位置上的数字的平方和
if(hash.find(n)!=hash.end()) return false;//重复出现说明死循环
}
return true;
}
};
力扣454四数相加
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int>num;
int res=0;
//先将其中两个数组的和存进map
//map的key是两个数组的和 value是这个和出现的次数
for(int i=0;i<nums1.size();i++){
for(int j=0;j<nums2.size();j++){
if(num.find(nums1[i]+nums2[j])==num.end())
num.insert(make_pair(nums1[i]+nums2[j],1));
else num[nums1[i]+nums2[j]]++;
}
}
//扫描num3和num4
for(int i=0;i<nums3.size();i++){
for(int j=0;j<nums4.size();j++){
if(num.find(0-nums3[i]-nums4[j])!=num.end()){
res+=num[0-nums3[i]-nums4[j]];//注意应该+value而不是+1
}
}
}
return res;
}
};
力扣15三数之和
注意去重逻辑
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());
int left,right;
for(int i=0;i<nums.size();i++){
if(nums[i]>0) return res;
if(i>0&&nums[i]==nums[i-1]) continue;//这是去重的逻辑
left=i+1;
right = nums.size()-1;
while(left<right){
//如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些
if(nums[i]+nums[left]+nums[right]>0){
right--;
}
//如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止
else if(nums[i]+nums[left]+nums[right]<0){
left++;
}
else {
//收获结果
res.push_back({nums[i],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;
}
};
四数之和
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for(int k=0;k<nums.size();k++){
//剪枝
if(nums[k]>target&&nums[k]>0&&target>0){
break;
}
//去重
if(k>0&&nums[k]==nums[k-1]){
continue;
}
for(int i=k+1;i<nums.size();i++){
//剪枝
if(nums[k]+nums[i]>target&&nums[k]+nums[i]>0&&target>0){
break;
}
//去重
if(i>k+1&&nums[i]==nums[i-1]){
continue;
}
int left=i+1,right=nums.size()-1;
while(left<right){
if((long)nums[k]+nums[i]+nums[left]+nums[right]<target) left++;
else if((long)nums[k]+nums[i]+nums[left]+nums[right]>target) right--;
else{
//收获
res.push_back({nums[k],nums[i],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;
}
};