Leetcode454
题目描述:
给你四个整数数组 nums1
、nums2
、nums3
和 nums4
,数组长度都是 n
,请你计算有多少个元组 (i, j, k, l)
能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
思路解析:
* 先枚举nums1和nums2组合的所有情况存储到map,至于为什么要这样,
* 主要是想降低时间复杂度到O(n*2)
* 再枚举nums3和nums4组合的所有情况,在map中查找是否存在对应的元素
代码及注释详解:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
//key值为和,value为出现的次数
unordered_map<int, int>umap;
for (int i = 0; i < nums1.size(); i++) {
for (int j = 0; j < nums2.size(); j++) {
//该和的相反值对应出现的次数加1
umap[-(nums1[i] + nums2[j])]++;
}
}
int ans = 0;
for (int i = 0; i < nums3.size(); i++) {
for (int j = 0; j < nums4.size(); j++) {
//存在对应值
if (umap.find(nums3[i] + nums4[j]) != umap.end()) {
ans += umap[(nums3[i] + nums4[j])];
}
}
}
return ans;
}
Leetcode383
题目描述:
给你两个字符串:ransomNote
和 magazine
,判断 ransomNote
能不能由 magazine
里面的字符构成。
如果可以,返回 true
;否则返回 false
。
magazine
中的每个字符只能在 ransomNote
中使用一次。
代码:
bool canConstruct(string ransomNote, string magazine) {
int cnt[26] = { 0 };
for (int i = 0; i < magazine.size(); i++) {
cnt[magazine[i] - 'a']++;
}
for (int i = 0; i < ransomNote.size(); i++) {
if (cnt[ransomNote[i] - 'a'] == 0)return false;
else cnt[ransomNote[i] - 'a']--;
}
return true;
}
Leetcode15
题目描述:
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
代码:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>>v;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size() - 2; i++) {
//去重
if (i > 0 && nums[i] == nums[i - 1])continue;
//提前跳出
if (nums[i] > 0)break;
int left = i + 1;
int right = nums.size() - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum < 0)left++;
else if (sum > 0)right--;
else {
v.push_back({ nums[i],nums[left],nums[right] });
left++;
//去重
while (left < right && nums[left] == nums[left - 1])left++;
//去重
right--;
while (left < right && nums[right] == nums[right + 1])right--;
}
}
}
return v;
}
Leetcode18
题目描述:
给你一个由 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
你可以按 任意顺序 返回答案 。
代码:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>>v;
if (nums.size() < 4) {
return v;
}
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size() - 3; i++) {
//剪枝
if ((long)nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
break;
}
//去重
if (i > 0 && nums[i] == nums[i - 1])continue;
for (int k = i + 1; k < nums.size() - 2; k++) {
//去重
if (k > (i + 1) && nums[k] == nums[k - 1])continue;
int left = k + 1;
int right = nums.size() - 1;
while (left < right) {
int sum = (long)nums[i] + nums[k] + nums[left] + nums[right];
if (sum < target)left++;
else if (sum > target)right--;
else {
v.push_back({ nums[i],nums[k],nums[left],nums[right] });
left++;
//去重
while (left < right && nums[left] == nums[left - 1])left++;
right--;
//去重
while (left < right && nums[right] == nums[right + 1])right--;
}
}
}
}
return v;
}