[Code Random Thoughts | Leetcode | Day 9] Hash Table | Happy Numbers | Addition of Four Numbers II | Ransom Letter

foreword

Welcome to Little K 's Leetcode|Code Random Thoughts | Specialized column, today I will bring you hashing~Happy Numbers|Addition of Four Numbers II|Sharing of Ransom Letter✨


202. Happy Numbers

✨Title linkClick here
to write an algorithm to judge whether a number n is a happy number.
"Happy Number" is defined as:

  • For a positive integer, each time the number is replaced by the sum of the squares of the digits in each position.
  • Then repeat this process until the number becomes 1, or it may be an infinite loop but it never becomes less than 1.
  • If the result of this process is 1, then the number is a happy number.
    Returns true if n is a happy number; otherwise, returns false.

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

hint:
1 <= n <= 231 - 1

Idea: The second definition of "happy number" - then repeat this process until the number becomes 1, or it may be an infinite loop but it will never change to 1, that is to say, when it repeats, the number is definitely not a happy number~ But when we want to quickly judge whether a number appears in the set, we naturally think of hashing sum!

class Solution {
    
    
public:
    int getSum(int n) {
    
    
        int sum = 0;
        while (n) {
    
    
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
    
    
        unordered_set<int> set;
        while (1) {
    
    
            int sum = getSum(n);
            if (sum == 1) {
    
    
                return true;
            }
            if (set.find(sum) != set.end()) {
    
    
                return false;
            }
            else set.insert(sum);
            n = sum;
        }
    }
};

insert image description here

454. Adding Four Numbers II

✨Title Link Click here
to give you four integer arrays nums1, nums2, nums3 and nums4, the length of the array 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

hint:

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

"The idea is as follows":

First define an unordered_map, the key puts the sum of a and b, and the value puts the number of occurrences of the sum of a and b.
Traverse the big A and big B arrays, count the sum of the elements of the two arrays, and the number of occurrences, and put them in the map.
Define the int variable count to count the number of occurrences of a+b+c+d = 0.
After traversing the big C and big D arrays, if 0-(c+d) has appeared in the map, use count to count the value corresponding to the key in the map, that is, the number of occurrences.
Finally, return the statistical value count

class Solution {
    
    
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
    
    
        //key存放nums1和nums2中值的和,value则记录该值出现的次数
        unordered_map<int,int> umap;
        //遍历nums1和nums2数值,记录他们的和出现的次数,并放入map中
        for (auto a : nums1) {
    
    
            for (auto b : nums2) {
    
    
                umap[a+b]++;
            }
        }
        int count = 0; //记录四数之和等于零
        //遍历nums3和nums4数组,如果他们的和等于map中任意一值的相反数,则用count记录该和出现的次数
        //也就是四数之和等于零的次数
        for (auto c : nums3) {
    
    
            for (auto d : nums4) {
    
    
                if (umap.find(- (c + d)) != umap.end()) {
    
    
                    count += umap[- (c + d)];
                }
            }
        }
        return count;
    }
};

insert image description here

383. Ransom letter

✨The title link click here
to give you two strings: ransomNoteand magazine , to judge ransomNote whether it can be magazine composed of characters inside. Return if yes true; otherwise return false. magazineEach character in can only ransomNote be used once in .

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

hint:
1 <= ransomNote.length, magazine.length<= 105
ransomNoteand magazine consists of lowercase English letters

"Method 1": Violent method, direct two-layer forloop, if there is an element of ransomNote in the magazine, then delete it from ransomNote, and finally check whether the size of ransomNote is zero

class Solution {
    
    
public:
    bool canConstruct(string ransomNote, string magazine) {
    
    
        for (int i = 0; i < magazine.size(); i++) {
    
    
            for (int j = 0; j < ransomNote.size(); j++) {
    
    
                if (magazine[i] == ransomNote[j]) {
    
    
                    ransomNote.erase(ransomNote.begin() + j);
                    break;
                }
            }
        }
        if (ransomNote.size() == 0) return true;
        return false;
    }
};

insert image description here

"Method 2": Hash method, my first idea is to use map, map idea, use letters as keys, use value to record the number of occurrences, first put ransomNote into the map, then use the map to find elements in the magazine, find one and subtract one, and finally check whether the values ​​in the map are less than or equal to zero.

class Solution {
    
    
public:
    bool canConstruct(string ransomNote, string magazine) {
    
    
        if (magazine.size() < ransomNote.size()) return false;
        unordered_map<char,int> umap;
        for (int i = 0; i < ransomNote.size() ; i++) umap[ransomNote[i]]++;
        for (int i = 0; i < magazine.size(); i++) umap[magazine[i]]--;
        for (int i = 0; i < ransomNote.size() ; i++) {
    
    
            if (umap[ransomNote[i]] > 0)
            return false;
        }
        return true;
    }
};

insert image description here

"Method 3": Because the map needs to maintain a red-black tree or a hash table, and also needs to do a hash function, it is time-consuming! So using an array as a hash table here is faster than a map! ! !

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

insert image description here

Summarize

Hash tables have three structures, arrays, set, map, and should be selected appropriately according to the situation~

Guess you like

Origin blog.csdn.net/qq_72157449/article/details/131832317