竞价培训班,佛山seo结算,域名续费一般多少钱一年,wordpress快速汉化主题● 454.四数相加II ● 383. 赎金信 ● 15. 三数之和 ● 18. 四数之和
总结
对于查#xff0c;某个元素是否在集合中出现过#xff0c;哈希法是非常高效的方法 但是对于需要去重的情况下#xff0c;哈希法要注意太多细节#xff0c;很难完美写完#xff0c;因此采用双指针…● 454.四数相加II ● 383. 赎金信 ● 15. 三数之和 ● 18. 四数之和
总结
对于查某个元素是否在集合中出现过哈希法是非常高效的方法 但是对于需要去重的情况下哈希法要注意太多细节很难完美写完因此采用双指针法更便于去重
● 454.四数相加II
/*454. 四数相加 II
中等给你四个整数数组 nums1、nums2、nums3 和 nums4 数组长度都是 n 请你计算有多少个元组 (i, j, k, l) 能满足
0 i, j, k, l n
nums1[i] nums2[j] nums3[k] nums4[l] 0*/#include unordered_mapclass Solution_454 {public:/** 暴力解法四层for循环显然时间复杂度很高* 给出等式可以根据等式遍历部分数组然后匹配查找需要的另外部分数组元素即查找某个元素在集合中是否出现过可以用哈希表并且不用去重。* 因为四个独立数组即使用哈希表也需要遍历求和只是可以分开求所以最好是两两分组最多是两层for循环* 那思路就是用map保存两个数组之和及其出现次数再遍历另外两个数组和在map查询满足等式的元素是否存在出现了多少次从而得到结果* 使用无序map,底层实现是哈希搜索效率高* O(n^2)*/int fourSumCount(vectorint nums1, vectorint nums2, vectorint nums3, vectorint nums4) {unordered_mapint, int record_map;for(auto a : nums1){//map保存两个数组之和及其出现次数for(auto b : nums2)record_map[a b];}int count 0;for(auto c : nums3){for(auto d : nums4){auto itr record_map.find((0 - (c d)));if(itr ! record_map.end())count itr-second;}}return count;}
};● 383. 赎金信
/*
383. 赎金信简单
给你两个字符串ransomNote 和 magazine 判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以返回 true 否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。
*/
#include unordered_set
class Solution_383 {public:/**查找某个元素在集合中是否出现过可以用哈希表* O(n),但是因为涉及到删除操作复杂度更高*/bool canConstruct(string ransomNote, string magazine) {unordered_multisetchar magazine_set(magazine.cbegin(), magazine.cend());for(auto i : ransomNote){auto itr magazine_set.find(i);if(itr ! magazine_set.end()){magazine_set.erase(itr);} elsereturn false;}return true;}/** 类似于242可以用数组来保存元素及其出现次数更快,* 还是哈希表思想* O(n),但是没有删除操作*/bool canConstruct_hash(string ransomNote, string magazine) {int record[26] {0};for(auto i : magazine){record[i - a] 1;}for(auto i : ransomNote){if(record[i - a] 0){record[i - a] - 1;} elsereturn false;}return true;}
};● 15. 三数之和
/** 15. 三数之和中等
提示给你一个整数数组 nums 判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k 同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。
注意答案中不可以包含重复的三元组。*/
#include algorithm
class Solution_15 {public:/** 暴力解法可以找到三元组但是不知道怎么去重**关键是三元组内部可重复但是多个三元组的元素不能重复所以应该对三个元素进行去重操作* 对第一个元素的去重重点在于由后一个元素判断前一个元素是否相同如果对前一个元素进行去重会使得类似{-1, -1, 2}这样的三元组被去掉* 对双指针指向的两个元素去重关键是得在拿到第一个符合条件的三元组之后进行去重负责类似于{0, 0, 0}这样的三元组会被去掉*///去重失败vectorvectorint threeSum(vectorint nums) {vectorvectorint res;sort(nums.begin(), nums.end());for(int i 0; i nums.size(); i){if(nums[i] 0)return res;if(i 0){nums[i] nums[i - 1];continue;}for(int j i 1; j nums.size(); j){if(j 0){nums[j] nums[j - 1];continue;}for(int k j 1; k nums.size(); k){if(k 0){nums[k] nums[k - 1];continue;}if(nums[i] nums[j] nums[k] 0)res.push_back(vectorint{nums[i], nums[j], nums[k]});}}}return res;}vectorvectorint threeSum_double_points(vectorint nums) {vectorvectorint res;sort(nums.begin(), nums.end());for (int i 0; i nums.size(); i) {if (nums[i] 0)return res;if (i 0) {//去重,跟前一个比较避免类似{-1, -1, 2}这样的三元组被去掉if (nums[i] nums[i - 1])continue;}int left i 1;int right nums.size() - 1;while (left right) {if (nums[i] nums[left] nums[right] 0) {res.push_back(vectorint{nums[i], nums[left], nums[right]});while (left right nums[left] nums[left 1])//去重left 1;while (left right nums[right] nums[right - 1])//去重right - 1;left 1;right - 1;} else if (nums[i] nums[left] nums[right] 0) {left 1;} else {right - 1;}}}return res;}
};
● 18. 四数之和
/*18. 四数之和中等
给你一个由 n 个整数组成的数组 nums 和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组[nums[a], nums[b], nums[c], nums[d]] 若两个四元组元素一一对应则认为两个四元组重复
0 a, b, c, d n
a、b、c 和 d 互不相同
nums[a] nums[b] nums[c] nums[d] target你可以按 任意顺序 返回答案 。*/class Solution_18 {public:/** 跟15相同的解法*/vectorvectorint fourSum(vectorint nums, int target) {vectorvectorint res;sort(nums.begin(), nums.end());for (int i 0; i nums.size(); i) {if(nums[i] target)return res;if(i 0 nums[i] nums[i - 1])continue;for (int j i 1; j nums.size(); j) {if(j 1 nums[j] nums[j - 1])continue;int left j 1;int right nums.size() - 1;while (left right) {if (nums[i] nums[j] nums[left] nums[right] target)left 1;else if (nums[i] nums[j] nums[left] nums[right] target)right - 1;else {res.push_back(vectorint{nums[i], nums[j], nums[left], nums[right]});while (left right nums[left] nums[left 1])left 1;while (left right nums[right] nums[right - 1])right - 1;left 1;right - 1;}}}}return res;}
};