LeetCode刷题 Day07
454. 4Sum II
Given four integer arrays nums1, nums2, nums3, and nums4 all of length n, return the number of tuples (i, j, k, l) such that:
0 <= i, j, k, l < nnums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
Example 1:
Input: nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
Output: 2
Explanation:
The two tuples are:
1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0
思路:
- 一轮循环: 利用hashset存储nums1和nums2数组元素两两相加的组合结果,并计数
- 二轮循环: 如果nums3 和nums4两两相加的结果的负值 正好出现在hashset中,则说明num1 + num2 + num3 + num4 为0, counter 加上之前的计数结果
代码:
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @param {number[]} nums3
* @param {number[]} nums4
* @return {number}
*/
var fourSumCount = function(nums1, nums2, nums3, nums4) {
let counter = 0;
let cache = {};
for (let num1 of nums1) {
for (let num2 of nums2) {
cache[num1 + num2] = cache[num1 + num2] ? ++cache[num1 + num2] : 1;
}
}
for (let num3 of nums3) {
for (let num4 of nums4) {
let neg = -1 * (num3 + num4);
if (cache[neg]) {
counter += cache[neg];
}
}
}
return counter;
};
时间复杂度: O(n2) 空间复杂度: O(n)
383. Ransom Note
Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise.
Each letter in magazine can only be used once in ransomNote.
Example 1:
Input: ransomNote = "a", magazine = "b"
Output: false
Example 2:
Input: ransomNote = "aa", magazine = "ab"
Output: false
Example 3:
Input: ransomNote = "aa", magazine = "aab"
Output: true
思路:
- 一轮循环: 通过hashset对ransomNote的字母进行计数
- 二轮循环: 做cache[ransomNote[i]]--处理,如果为undefined或者<0,return false
代码:
/**
* @param {string} ransomNote
* @param {string} magazine
* @return {boolean}
*/
var canConstruct = function(ransomNote, magazine) {
let cache = {};
for (let i = 0; i < magazine.length; i++) {
cache[magazine[i]] = cache[magazine[i]] ? ++cache[magazine[i]] : 1;
}
for (let i = 0; i < ransomNote.length; i++) {
if (cache[ransomNote[i]] === undefined) return false;
cache[ransomNote[i]]--;
if (cache[ransomNote[i]] < 0) return false;
}
return true;
};
15. 3Sum
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets.
Example 1:
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Explanation:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.
The distinct triplets are [-1,0,1] and [-1,-1,2].
Notice that the order of the output and the order of the triplets does not matter.
Example 2:
Input: nums = [0,1,1]
Output: []
Explanation: The only possible triplet does not sum up to 0.
Example 3:
Input: nums = [0,0,0]
Output: [[0,0,0]]
Explanation: The only possible triplet sums up to 0.
思路:
- 这是一个三指针
- 排序
- 设定好i, left(i + 1), right (length - 1)
- 在循环中skip掉重复的, num[i], num[left], num[right]
代码:
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
let sum = 0;
let res = [];
nums.sort((a, b) => a - b);
for (let i = 0; i < nums.length; i++) {
let left = i + 1;
let right = nums.length - 1;
if (i > 0 && nums[i] === nums[i - 1]) continue;
while (left < right) {
sum = nums[left] + nums[right] + nums[i];
if (sum < 0) left++;
else if (sum > 0) right--;
else {
res.push([nums[i], nums[left], nums[right]]);
while (left < right && nums[left] === nums[left + 1]) left++;
while (left < right && nums[right] === nums[right - 1]) right--;
left++;
right--;
}
}
}
return res;
};
时间复杂度: O(n2) 空间复杂度: O(1)
18. 4Sum
Given an array nums of n integers, return an array of all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]] such that:
0 <= a, b, c, d < na,b,c, anddare distinct.nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.
Example 1:
Input: nums = [1,0,-1,0,-2,2], target = 0
Output: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
Example 2:
Input: nums = [2,2,2,2,2], target = 8
Output: [[2,2,2,2]]
思路:
- 和3sum思路相同,再加一层循环
代码:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[][]}
*/
var fourSum = function(nums, target) {
let sum = 0;
let res = [];
nums.sort((a, b) => a - b);
for (let i = 0; i < nums.length - 1; i++) {
if (i > 0 && nums[i] === nums[i - 1]) continue;
for (let j = i + 1; j < nums.length - 1; j++) {
if (j > i + 1 && nums[j] === nums[j - 1]) continue;
let left = j + 1;
let right = nums.length - 1;
while(left < right) {
sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum < target) left++;
else if (sum > target) right--;
else {
res.push([nums[i], nums[j], nums[left], nums[right]]);
while (left < right && nums[left] === nums[left + 1]) left++;
while (left < right && nums[left] === nums[right - 1]) right--;
left++;
right--;
}
}
}
}
return res;
};
时间复杂度: O(n3) 空间复杂度: O(1)