Journey of LeetCode|DAY 6
Preface
This is a new day to continue my Hash Table journey.
Learn something new and keep reviewing what I learnt before.
1. 4Sum II
LeetCode Link: 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 < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
Analysis and Solution
Unordered Map
LeetCode C++ as followings Unordered Map
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
unordered_map<int, int> umap; //include key and value;key:sum of a+b,value:frequency of a+b
// traverse A and B;assign sum and frequency to map
for (int a : A) {//assign per element to a from A,for loop
for (int b : B) {//assign per element to b from B,for loop
umap[a + b]++;//get the sum of a+b;and record frequency of a+b
}
}
int count = 0; // record the frequency of a+b+c+d
// traverse C and D,if 0-(c+d) appeared in the map,record frequency of a+b+c+d
for (int c : C) {//same as before
for (int d : D) {//same as before
if (umap.find(0 - (c + d)) != umap.end()) {// If the given key exists in unordered_map it returns an iterator to that element otherwise it returns the end of the map iterator.
count += umap[0 - (c + d)];//count=count+umap[0 - (c + d)]
}
}
}
return count;
}
};
2. Ransom Note
LeetCode Link: 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.
Analysis and Solution
Double For
LeetCode C++ as followings Double For
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
for (int i = 0; i < magazine.length(); i++) {//traverse magazine
for (int j = 0; j < ransomNote.length(); j++) {//traverse ransomNote
if (magazine[i] == ransomNote[j]) {//find same element of two
ransomNote.erase(ransomNote.begin() + j); // delete this element in ransomNote (1)string& erase ( size_t pos = 0, size_t n = npos );(2)iterator erase ( iterator position );(3)iterator erase ( iterator first, iterator last );
break;
}
}
}
// if ransomNote is empty,which means the elements of magazine can form ransomNote
if (ransomNote.length() == 0) {
return true;
}
return false;
}
};
Hash Array
LeetCode C++ as followings Hash Array
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int record[26] = {0};//define a hash array
//if ransomNote > magazine, it definitely cannot form ransomNote from magazine
if (ransomNote.size() > magazine.size()) {
return false;
}
for (int i = 0; i < magazine.length(); i++) {//traverse magazine
// record the frequency of per element in the magazine
record[magazine[i]-'a'] ++;//use ASCII to calculate ,and get the location of the record, +1 there
}
for (int j = 0; j < ransomNote.length(); j++) {//traverse ransomNote
record[ransomNote[j]-'a']--;//same as before , -1 at the area of the array
if(record[ransomNote[j]-'a'] < 0) {//if <0,which means some elements cannot match by magazine
return false;
}
}
return true;
}
};
3. 3Sum
LeetCode Link: 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.
Analysis and Solution
Hash Table
LeetCode C++ as followings Hash Table
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;//define a result array
sort(nums.begin(), nums.end());//sort the array
// define a = nums[i], b = nums[j], c = -(a + b),find a+b+c=0
for (int i = 0; i < nums.size(); i++) {//traverse array
if (nums[i] > 0) {//a+b+c cannot = 0, if first element of array > 0
break;
}
if (i > 0 && nums[i] == nums[i - 1]) { //remove the repeat value of a
continue;
}
unordered_set<int> set;//define a hash set
for (int j = i + 1; j < nums.size(); j++) {//traverse j
if (j > i + 2
&& nums[j] == nums[j-1]
&& nums[j-1] == nums[j-2]) { // remove the repeat value of b
continue;
}
int c = 0 - (nums[i] + nums[j]);//define c
if (set.find(c) != set.end()) {//find function If the given key exists in unordered_map it returns an iterator to that element otherwise it returns the end of the map iterator.
result.push_back({nums[i], nums[j], c});//The C++ function std::vector::push_back() inserts new element at the end of vector and increases size of vector by one.
set.erase(c);// remove the repeat value of c
} else {
set.insert(nums[j]);//insert b
}
}
}
return result;
}
};
Double Pointer
LeetCode C++ as followings Double Pointer
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;//define a array
sort(nums.begin(), nums.end());//sort array
// define a = nums[i], b = nums[left], c = nums[right]
for (int i = 0; i < nums.size(); i++) {//traverse array
// a+b+c cannot = 0, if first element of array > 0
if (nums[i] > 0) {
return result;
}
// wrong way to remove repeat value,which will ignore-1,-1,2
/*
if (nums[i] == nums[i + 1]) {
continue;
}
*/
// remove repeat value a
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1;//define b
int right = nums.size() - 1;//define c
while (right > left) {
// if remove repeat value here,the situation 0,0,0 ,which lead right<=left ,may ignore 000
/*
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
*/
if (nums[i] + nums[left] + nums[right] > 0) right--;//move c pointer
else if (nums[i] + nums[left] + nums[right] < 0) left++;//move b pointer
else {
result.push_back(vector<int>{nums[i], nums[left], nums[right]});//The C++ function std::vector::push_back() inserts new element at the end of vector and increases size of vector by one.
// remove the repeat value of b and c
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
// double pointer retarcted after found answer
right--;
left++;
}
}
}
return result;
}
};
4. 4Sum
LeetCode Link: 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 < n
a, b, c, and d are distinct.
nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.
Analysis and Solution
Double Pointer
LeetCode C++ as followings Double Pointer
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;//define a array named result
sort(nums.begin(), nums.end());//sort array
for (int k = 0; k < nums.size(); k++) {//traverse array
// delete the branch;
if (nums[k] > target && nums[k] >= 0) {// K should be smallest num after sorting, if K>0,and K>target,it cannot get target with others.
break; // use Break to return together at last
}
// remove the repeat value of K
if (k > 0 && nums[k] == nums[k - 1]) {//judge K ?= K-1
continue;//The continue statement breaks one iteration (in the loop), if a specified condition occurs, and continues with the next iteration in the loop.
}
for (int i = k + 1; i < nums.size(); i++) {//traverse i
// delete the second branch
if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) {//if K+i>0,and K+i>target,it cannot get target with others(4 nums).
break;
}
// remove the repeat value of nums[i]
if (i > k + 1 && nums[i] == nums[i - 1]) {//judge i ?= i-1
continue;//The continue statement breaks one iteration (in the loop), if a specified condition occurs, and continues with the next iteration in the loop.
}
int left = i + 1;//define a pointer(left)
int right = nums.size() - 1;//define a pointer(right)
while (right > left) {//judge in a loop
// nums[k] + nums[i] + nums[left] + nums[right] > target ;it would overflow
if ((long) nums[k] + nums[i] + nums[left] + nums[right] > target) {
right--;//move right to a smaller num
// nums[k] + nums[i] + nums[left] + nums[right] < target ;it would overflow
} else if ((long) nums[k] + nums[i] + nums[left] + nums[right] < target) {
left++;//move left to a bigger one
} else {
result.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]});//The C++ function std::vector::push_back() inserts new element at the end of vector and increases size of vector by one.
// remove the repeat value of nums[left] amd nums[right]
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
// double pointers move to middle at the same time after found answer
right--;
left++;
}
}
}
}
return result;
}
};