题目:给定n个整数,k以及target,在这n个数里找k个数,使得这k个数的和等于target,输出所有可能的方案。
解法:若k为偶数,则先对n个整数排序,然后求出每k/2个数的和(如在4sum问题中求出每两个数的和)存在HashMap中(key:两数和 value:求和的两个数的数组下标的集合),遍历Hashmap,若对于当前元素x存在target-x也在HashMap中,则将x和target-x对应的下标集合两两配对产生一个解,过程中需要去重(目前只想到先将配对后的包含k个下标的数组排序,然后用set去重)。
若k为奇数,则先对n个整数排序,然后求出每k/2个数的和存在HashMap中。遍历数组,若对当前元素a,HashMap中存在一对x和target-a-x,则将x和target-a-x对应的下标集合两两配对产生一个解,过程中需要去重。
class Solution { public: void mergeTwoSum(vector<int>& nums, set<vector<int>>& res, vector<vector<int>> list1, vector<vector<int>> list2) { for (int i = 0; i < list1.size(); i++) { for (int j = 0; j < list2.size(); j++) { if (list1[i][0] == list2[j][0] || list1[i][1] == list2[j][0]) continue; if (list1[i][0] == list2[j][1] || list1[i][1] == list2[j][1]) continue; vector<int> temp; temp.push_back(nums[list1[i][0]]); temp.push_back(nums[list1[i][1]]); temp.push_back(nums[list2[j][0]]); temp.push_back(nums[list2[j][1]]); sort(temp.begin(), temp.end()); res.insert(temp); } } } vector<vector<int>> fourSum(vector<int>& nums, int target) { int n = nums.size(); vector<vector<int>> res; set<vector<int>> res_set; map<int, vector<vector<int>>> twoSum; sort(nums.begin(), nums.end()); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { vector<int> temp; temp.push_back(i); temp.push_back(j); twoSum[nums[i] + nums[j]].push_back(temp); } } map<int, vector<vector<int>>>::iterator it; for (it = twoSum.begin(); it != twoSum.end(); it++) { int a = it->first; int b = target - a; if (a > b) break; if (twoSum.find(b) != twoSum.end()) mergeTwoSum(nums, res_set, it->second, twoSum[b]); } res.assign(res_set.begin(), res_set.end()); return res; } };
原文:https://www.cnblogs.com/alderheart/p/10958576.html