# [LeetCode] - hash table

Posted by hoboman on Thu, 03 Feb 2022 08:15:49 +0100

# preface

When I first know LeetCode and algorithm, I will record my algorithm learning experience in this series of articles. In the early stage, I mainly supervise my learning and clock in. In the later stage, I will slowly add my understanding of knowledge to the articles. I hope you can gain something from reading my articles. The order of this series of articles is Code Capriccio As a clue.

# 1, Valid Letter ectopic words

Title:
Given two strings s and t, write a function to judge whether t is an alphabetic ectopic word of s.

Note: if each character in S and t appears the same number of times, s and T are called alphabetic words.

Example 1:

Input: s = "anagram", t = "nagaram"
Output: true

Example 2:

Input: s = "rat", t = "car"
Output: false

Tips:

```1 <= s.length, t.length <= 5 * 104
s and t Contains only lowercase letters
```

Idea:
1. Violent solution is to write two for loops to compare
2. Instead of comparing the values of the array, you only need to compare the number of occurrences of characters

code:

```class Solution {
public:
bool isAnagram(string s, string t) {
int record[26] = {0};
for(int i = 0; i < s.size(); i++ ){
record[s[i] - 'a']++;
}
for(int i = 0; i < t.size(); i++){
record[s[i] - 'a']--;
}
for(int i = 0; i < 26; i++){
if(record[i] != 0){
return false;
}
}
return true;

}
};
```

# 2, Intersection of two arrays

Title:
Given two arrays nums1 and nums2, return their intersection. Each element in the output result must be unique. We can ignore the order of output results.

Example 1:

Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2]

Example 2:

Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [9,4]
Explanation: [4,9] is also acceptable

Tips:

```1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
```

Idea:
1. Violent solution is to write two for loops and compare them one by one
2. Using hash table, unorder in set container_ Set data structure. The feature of this structure is that key can be used to find without repetition;

code:

```class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set;
unordered_set<int> nums_set(nums1.begin(),nums1.end());
for(int num:nums2){
if(nums_set.find(num) != nums_set.end()){
result_set.insert(num);
}
}
return vector<int>(result_set.begin(),result_set.end());
}
};
```

# 3, Happy number

Title:
Write an algorithm to judge whether a number n is a happy number.

"Happy number" is defined as:

```For a positive integer, replace the number with the sum of the squares of the numbers at each position each time.
Then repeat the process until the number becomes 1, or it may be an infinite loop, but it never becomes 1.
If the result of this process is 1, then this number is the number of happiness.
```

If n is a happy number, return true; If not, false is returned.

Example 1:

Input: n = 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

Example 2:

Input: n = 2
Output: false

Tips:

```1 <= n <= 231 - 1
```

Idea:
1. When you need to quickly judge whether an element appears in the set, you need to consider the hash method.
2. Compilation of summation function

code:

```class Solution {
public:

int getSum(int n){
int sum = 0;
while(n){
sum += (n%10)*(n%10);
n = n/10;
}
return sum;
}

bool isHappy(int n) {
unordered_set<int> set;
while(1){
int sum = getSum(n);
if(sum == 1){
return true;
}else{
if(set.find(sum) != set.end()){
return false;
}else{
set.insert(sum);
}
}
n = sum;
}
}
};
```

# 4, Sum of two numbers

Title:
Given an integer array nums and an integer target value target, please find the two integers with and as the target value target in the array and return their array subscripts.

You can assume that each input will correspond to only one answer. However, the same element in the array cannot appear repeatedly in the answer.

You can return answers in any order.

Example 1:

Input: num = [2,7,11,15], target = 9
Output: [0,1]
Explanation: because num [0] + num [1] = = 9, return [0, 1].

Example 2:

Input: num = [3,2,4], target = 6
Output: [1,2]

Example 3:

Input: num = [3,3], target = 6
Output: [0,1]

Tips:

```2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
There will only be one valid answer
```

Advanced: can you think of an algorithm with less time complexity than O(n2)?

Idea:
1. Violent solution is to write two for loops for calculation and comparison
2. The hash table method is used to map the target value with the difference in the table. Through this method, only one for loop is needed

code:

```class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
std::unordered_map <int,int>map;
for(int i = 0; i < nums.size(); i++){
auto iter = map.find(target - nums[i]);
if(iter != map.end()){
return {iter->second,i};
}
map.insert(pair<int,int>(nums[i],i));
}
return {};

}
};
```

# 5, Four number addition II

Title:
Here are four integer arrays nums1, nums2, nums3 and nums4. The array length is n. please calculate how many tuples (i, j, k, l) can satisfy:

```0 <= i, j, k, l < n
nums1[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 as follows:

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

Example 2:

Input: nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0]
Output: 1

Tips:

```n == nums1.length
n == nums2.length
n == nums3.length
n == nums4.length
1 <= n <= 200
-228 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 228
```

Idea:
1. The hash table method is used to add and store nums1 and nums2 arrays, and then judge whether the difference exists in the hash table by 0-[nums3+nums4].

code:

```class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
std::unordered_map<int,int> umap;
for(int a : nums1){
for(int b : nums2){
umap[a+b]++;
}
}
int count = 0;
for(int c : nums3){
for(int d : nums4){
if(umap.find(0 - (c + d)) != umap.end()){
count += umap[0 - (c + d)];
}
}
}

return count;

}
};
```

# 6, Ransom letter

Title:
Give you two strings: ransomNote and magazine. Judge whether ransomNote can be composed of characters in magazine.

If yes, return true; Otherwise, false is returned.

Each character 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

Tips:

```1 <= ransomNote.length, magazine.length <= 105
ransomNote and magazine It consists of lowercase English letters
```

Idea:
1. Violent solution, two for loops
2. Hash table mapping method, using array.

code:

```class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int record[26] = {0};
for(int i = 0; i < magazine.length(); i++){
record[magazine[i]-'a']++;
}
for(int j = 0; j < ransomNote.length(); j++){
record[ransomNote[j]-'a']--;
if(record[ransomNote[j]-'a'] < 0){
return false;
}
}
return true;

}
};
```

# 7, Sum of three

Title:
Give you an array num containing n integers. Judge whether there are three elements a, b and c in num, so that a + b + c = 0? Please find all triples with sum 0 and no repetition.

Note: the answer cannot contain duplicate triples.

Example 1:

Input: num = [- 1,0,1,2, - 1, - 4]
Output: [- 1, - 1,2], [- 1,0,1]]

Example 2:

Input: num = []
Output: []

Example 3:

Input: num = [0]
Output: []

Tips:

```0 <= nums.length <= 3000
-105 <= nums[i] <= 105
```

Idea:
1. Hash table method
2. Double pointer method

code:

```class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int i = 0; i < nums.size(); i++){
if(nums[i] > 0){
return result;
}
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
int left = i + 1;
int right = nums.size() - 1;
while(right > left){
if(nums[i] + nums[left] + nums[right] > 0){
right--;
}else if(nums[i] + nums[left] + nums[right] < 0){
left++;
}else{
result.push_back(vector<int>{nums[i],nums[left],nums[right]});
while(right > left && nums[right] == nums[right - 1]) right--;
while(right > left && nums[left] == nums[left + 1 ]) left++;

right--;
left++;
}
}
}
return result;
}
};
```

# 8, Sum of four numbers

Title:
Give you an array of n integers, nums, and a target value, target. Please find and return the quads [nums[a], nums[b], nums[c], nums[d]] (if the two Quad elements correspond one to one, it is considered that the two quads are repeated):

```0 <= a, b, c, d < n
a,b,c and d Different from each other
nums[a] + nums[b] + nums[c] + nums[d] == target
```

You can return answers in any order.

Example 1:

Input: num = [1,0, - 1,0, - 2,2], target = 0
Output: [[- 2, - 1,1,2], [- 2,0,0,2], [- 1,0,0,1]]

Example 2:

Input: num = [2,2,2,2,2], target = 8
Output: [[2,2,2,2]]

Tips:

```1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109
```

Idea:
1. Double finger needle method is adopted, and two cycles are added outside.

code:

```class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int k = 0; k < nums.size(); k++){
if(k > 0 && nums[k] == nums[k - 1]){
continue;
}

for(int i = k + 1; i < nums.size(); i++){
if(i > k + 1 && nums[i] == nums[i - 1]){
continue;
}
int left = i + 1;
int right = nums.size() - 1;
while(right > left){
if(nums[k] + nums[i] > target - (nums[left] + nums[right])){
right--;
}else if(nums[k] + nums[i] < target - (nums[left] + nums[right])){
left++;
}else{
result.push_back(vector<int>{nums[k],nums[i],nums[left],nums[right]});

while(right > left && nums[right] == nums[right - 1]) right--;
while(right > left && nums[left] == nums[left + 1])  left++;

right--;
left++;
}
}
}
}
return result;
}

};
```

Topics: Algorithm leetcode