题目链接:454.四数相加II
数组分为两组+map。时间复杂度。
三层循环+map。时间复杂度。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int result = 0;
unordered_map<int, int> hash;
for(int i = 0; i < nums1.size(); i++) {
for(int j = 0; j < nums2.size(); j++) {
if(hash.find(nums1[i] + nums2[j]) != hash.end()){
(hash.find(nums1[i] + nums2[j]))->second++;
}
else {
hash[nums1[i] + nums2[j]] = 1;
}
}
}
for(int i = 0; i < nums3.size(); i++) {
for(int j = 0; j < nums4.size(); j++) {
if(hash.find(0 - nums3[i] - nums4[j]) != hash.end())
result += hash.find(0 - nums3[i] - nums4[j])->second;
}
}
return result;
}
};
题目链接:383. 赎金信
关键:ransomNote 和 magazine 由小写英文字母组成,由此可以使用数组。
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int hash[26] = {0};
for(int i = 0; i < magazine.length(); i++) {
hash[magazine[i] - 'a']++;
}
for(int i = 0; i < ransomNote.length(); i++) {
hash[ransomNote[i] - 'a']--;
if(hash[ransomNote[i] - 'a'] < 0)
return false;
}
return true;
}
};
题目链接:15. 三数之和
排序之后固定一个指针,让两个指针至于首尾向两个方向移动。
要点:结果去重。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
int i = 0, j, k;
while(i < nums.size() && nums[i] <= 0) {
j = i + 1;
k = nums.size() - 1;
while(j < k) {
if(nums[i] + nums[j] + nums[k] < 0) {
j++;
while(j < k && nums[j - 1] == nums[j]) {
j++;
}
}
else if(nums[i] + nums[j] + nums[k] > 0) {
k--;
while(k > j && nums[k + 1] == nums[k]) {
k--;
}
}
else {
result.push_back(vector<int>{nums[i], nums[j], nums[k]});
j++;
while(j < k && nums[j - 1] == nums[j]) {
j++;
}
}
}
i++;
while(i < j && nums[i - 1] == nums[i])
i++;
}
return result;
}
};
题目链接:18. 四数之和
方法与三数之和相同,注意剪枝操作的变量符号的分开考虑。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
if(nums.size() < 4) return result;
sort(nums.begin(), nums.end());
int a = 0, b, c, d = nums.size() - 1;
while(a <= nums.size() - 4) {
if (nums[a] >= 0 && nums[a] > target) break; //剪枝操作
b = a + 1;
while(b <= nums.size() - 3) {
c = b + 1;
d = nums.size() - 1;
if(nums[a] + nums[b] >= 0 && nums[a] + nums[b] > target) break; //剪枝操作
else if (nums[d] <= 0 && nums[d] < target) break; //剪枝操作
while(c < d) {
if((long)nums[a] + nums[b] + nums[c] + nums[d] == target) { //这个狗题目竟然有溢出
result.push_back(vector<int>{nums[a], nums[b], nums[c], nums[d]});
c++;
while(c < d && nums[c - 1] == nums[c]) c++;
}
else if((long)nums[a] + nums[b] + nums[c] + nums[d] < target) {
c++;
while(c < d && nums[c - 1] == nums[c]) c++;
}
else {
d--;
while(c < d && nums[d + 1] == nums[d]) d--;
}
}
b++;
while(b <= nums.size() - 3 && nums[b - 1] == nums[b]) b++;
}
a++;
while(a <= nums.size() - 4 && nums[a - 1] == nums[a]) a++;
}
return result;
}
};