bool isAnagram(string s, string t) {
unordered_map<char,int>hash1;//用一个哈希表存储元素出现次数
for(int i=0;i<s.size();i++){//将s的元素遍历,用hash1记录每个元素出现次数
hash1[s[i]]++;
}
for(int j=0;j<t.size();j++){//对t遍历
//如果t中元素在s中没找到,说明肯定不是字母异位词,返回false
//如果找到了
if(hash1.find(t[j])!=hash1.end()){
hash1[t[j]]--;//对应的元素个数--
//如果没了,则删除
if(hash1[t[j]]==0){
hash1.erase(hash1.find(t[j]));
}
}
else{
return false;
}
}
//最后如果哈希表为空
if(hash1.size()==0)return true;
else{
return false;
}
}
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int>hash;//定义hash记录nums1中元素
unordered_set<int>hashone;//记录返回元素
for(int i=0;i<nums1.size();i++){
hash.insert(nums1[i]);
}
for(int j=0;j<nums2.size();j++){
if(hash.find(nums2[j])!=hash.end())//如果发现一样的
hashone.insert(nums2[j]);
}
return vector<int>(hashone.begin(),hashone.end());
}
bool canConstruct(string ransomNote, string magazine) {
unordered_map<char,int>hash1;//用一个哈希表存储元素出现次数
for(int i=0;i<magazine.size();i++){//将magazine的元素遍历,用hash1记录每个元素出现次数
hash1[magazine[i]]++;
}
for(int j=0;j<ransomNote.size();j++){//对ran遍历
//如果ran中元素在magg中没找到,说明肯定构成不了,返回false
//如果找到了
if(hash1.find(ransomNote[j])!=hash1.end()){
hash1[ransomNote[j]]--;//对应的元素个数--
//如果没了,则删除,删除后再出现这个字符会返回false
if(hash1[ransomNote[j]]==0){
hash1.erase(hash1.find(ransomNote[j]));
}
}
else{
return false;
}
}
return true;
}
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int>hash;//建立哈希表来存储出现过的数字的下标
for(int i=0;i<nums.size();i++){
//如果发现符合条件的,返回
if(hash.find(target-nums[i])!=hash.end()){
return {i,hash[target-nums[i]]};
}
//没发现,将当前遍历的数和数的下标加入哈希表
else{
hash[nums[i]]=i;
}
}
return {};
}
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int>hash;//用哈希表记录一二数组每个和,每个和出现的次数
int count=0;
for(int i=0;i<nums1.size();i++){
for(int j=0;j<nums2.size();j++){
hash[nums1[i]+nums2[j]]++;
}
}
//遍历三四数组,如果符合条件,则一二数组中对应元素出现次数加上即可
for(int i=0;i<nums3.size();i++){
for(int j=0;j<nums4.size();j++){
if(hash.find(-nums3[i]-nums4[j])!=hash.end()){
count+=hash[-nums3[i]-nums4[j]];
}
}
}
return count;
}
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>>result;
sort(nums.begin(),nums.end());//先排序
int i=0;int j=0;int k=nums.size()-1;
for(i=0;i<nums.size();i++){
if(nums[i]>0)return result;//如果排序完成,第一个元素大于0,后面肯定不可能成立,可以直接返回
//去重,注意首先不能写成nums[i]==nums[i+1],这样会忽略掉-1,-1,2这种情况
//另外,continue不可以写成i++,不然当i==nums.size()了还会进入下面的步骤
if(i>0&&nums[i]==nums[i-1]){
continue;
}
j = i + 1;
k = nums.size() - 1;
//定义两个指针,一个从i+1开始,一个从数组最后开始,相交了则跳出循环
for(;j<k;){
//大于0的话,k--,注意这里和滑动窗口不一样,滑动窗口是收缩多次一起完成,这个是收缩一次
//再重新判断循环条件
if(nums[i]+nums[j]+nums[k]>0){
k--;
}
else if(nums[i]+nums[j]+nums[k]<0){
j++;
}
else{
result.push_back(vector<int>{nums[i], nums[j], nums[k]});
//去重,不可以先去重再导入res,这样会漏掉0,0,0这种情况。
while(j<k&&nums[j]==nums[j+1])j++;
while(j<k&&nums[k]==nums[k-1])k--;
//去重完成还要收缩
j++;
k--;
}
}
}
return result;
}
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>>result;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++){
if(nums[i]>target&&nums[i]>=0){
return result;
}
if(i>0&&nums[i]==nums[i-1]){
continue;
}
for(int j=i+1;j<nums.size();j++){
if(nums[j]>target-nums[i]&&nums[i]+nums[j]>=0){
break;//这里不能直接返回,因为上面还没结束
}
if(j>i+1&&nums[j]==nums[j-1]){
continue;
}
int m=j+1;int n=nums.size()-1;
while(m<n){
if((long)nums[i]+nums[j]+nums[m]+nums[n]<target){
m++;
}
else if((long)nums[i]+nums[j]+nums[m]+nums[n]>target){
n--;
}
else{
result.push_back(vector<int>{nums[i],nums[j],nums[m],nums[n]});
while(m<n&&nums[m]==nums[m+1])m++;//不加这个可能数组会越界,0,0,0,0这种
while(m<n&&nums[n]==nums[n-1])n--;
m++;
n--;
}
}
}
}
return result;
}