Hash Table [Sum of X Numbers]

Questions Guide

to sum up(***)

1. Reduce the time complexity in the loop: sort + double pointer, hash table
2. When there are multiple variables, for example, a[i] + a[j] == 0, you can fix j, that is, find 0 ~ Whether there is the number -a[j] in j-1, you can calculate while calculating
3. Hash table: count the number of occurrences!
4. Double pointers: double pointers can be considered when monotonicity is satisfied

Common method of hash table: counting the number of occurrences

Hashing also sacrifices space in exchange for time

242. Valid Letter Alien Words

Analysis:
Use a hash table to count the number of times each character appears, and the time complexity O(n). The first time I did it, it was sorted directly, which was time-complex O(nlogn).
Of course, the mapping range of this question is relatively small, and you can use an array as a hash table. If the range of advanced problems is large, arrays should not be used.
"And if the hash value is relatively small, particularly scattered, and the span is very large, the use of arrays will cause a huge waste of space."

class Solution {
    
    
public:
    bool isAnagram(string s, string t) {
    
    
        // 时间复杂度O(n)
        // 空间复杂度O(26)
        if(s.size() != t.size()) return false;

        unordered_map<char,int> cnt; // 哈希表
        for(auto c : s) cnt[c] ++;

        for(auto c : t){
    
    
            cnt[c] -- ;
        }

        for(auto x : cnt){
    
    
            if(x.second != 0) return false;
        }
        return true;
    }
};

349. Intersection of two arrays

Solution 1: Useunordered_set

class Solution {
    
    
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    
    
        // 时间复杂度O(n)
        unordered_set<int> num, res;
        for(auto c : nums1) num.insert(c); // 把nums1的元素插到unordered_set中
        
        for(auto c : nums2)
            if(num.count(c)) res.insert(c);
        
        vector<int> ans(res.begin(), res.end()); // 赋值
        return ans;
    }
};

Solution 2: Useunordered_map

class Solution {
    
    
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    
    
        // 哈希表

        unordered_map<int,int> hash;
        for(auto c : nums1) hash[c] ++ ;

        vector<int> res;
        for(auto c : nums2)
        {
    
    
            if(hash[c] > 0 ) res.push_back(c), hash[c] = 0 ;
        }

        return res;
    }
};

202. Happy Number

Analysis: The
title says "infinite loop", which means "in the process of summing sum会重复出现, this is very important for solving the problem!"

class Solution {
    
    
public:
    bool isHappy(int n) {
    
    
        unordered_map<int,int> cnt;
        while(n != 1)
        {
    
    
            cnt[n] ++;
            dfs(n); // 引用改变n的值
            if(cnt[n] > 1) return false; // 只要出现次数大于1,说明循环了
        }

        return true;
    }

    void dfs(int &n)
    {
    
    
        int res = 0;
        while(n > 0){
    
    
            int t = n % 10;
            res += t * t;
            n /= 10;
        }
        n = res;
    }
};

1. the sum of two numbers

Analysis:
One-time statistics is not very good, it is better to insert while seeking

class Solution {
    
    
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    
    
        unordered_map<int,int> hash;
        // 边求边插入
        for(int i = 0;i < nums.size();i ++ ){
    
    
            if(hash.count(target - nums[i])) return {
    
    hash[target - nums[i]], i};
            hash[nums[i]] = i;
        }
        return {
    
    -1, -1};
    }
};

454. Four Number Addition II

Analysis: It is
observed N = 500that at most two arrays can be looped. Common handling methods!

class Solution {
    
    
public:
    int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
    
    
        unordered_map<int,int> hash; //  统计 a + b的值出现的次数
        for(int i = 0;i < A.size();i ++ )
            for(int j = 0;j < B.size();j ++)
                hash[A[i] + B[j]] ++;
                
        int res = 0;
        for(int i = 0;i < C.size();i ++ )
            for(int j = 0;j < D.size();j ++)
            {
    
    
                int s = C[i] + D[j];
                if(hash.count(0 - s)) res += hash[0 - s]; // 这里的处理类似 两数之和
            }
        return res;
    }
};

383. Ransom Letter

class Solution {
    
    
public:
    bool canConstruct(string r, string m) {
    
    
        // 哈希计数
        unordered_map<char,int> cnt;
        for(auto c : m) cnt[c] ++;

        for(auto c : r){
    
    
            cnt[c] -- ;
            if(cnt[c] < 0) return false; // 字符不够了
        }
        return true;
    }
};

15. The sum of three numbers (sort + double pointer)

Analysis: sort + double pointer
hash table needs to be deduplicated and too difficult to write, use sort + double pointer instead, the event complexity is O(n ^ 2)
to find a[i] + a[l] + a[r] == 0, a[i] can be enumerated. Because of the previous sorting, monotonicity must be satisfied. As i moves, l and r will move monotonously, so double pointers can be used.
去重的常用操作: The difficulty of this question is also to remove the duplication!

while(l < r && nums[l] == nums[l - 1]) l ++ ;
while(l < r && nums[r] == nums[r + 1]) r -- ;
class Solution {
    
    
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    
    
        vector<vector<int>> res;

        int n = nums.size();
        if(n < 3) return res;
        sort(nums.begin(), nums.end());

        // a[i] + a[l] + a[r] == 0 , 固定a[i]
        for(int i = 0;i < n;i ++ )
        {
    
    
            if(nums[i] > 0) return res; // 直接返回了
            if(i != 0 && nums[i] == nums[i - 1]) continue; // 去重!关键!
            int l = i + 1, r = n - 1;
            while(l < r)
            {
    
    
                if(nums[l] + nums[i] + nums[r] == 0) {
    
    
                    res.push_back({
    
    nums[i], nums[l], nums[r]});
                    l ++ , r -- ;
                    // 去重的常见操作
                    while(l < r && nums[l] == nums[l - 1]) l ++ ;
                    while(l < r && nums[r] == nums[r + 1]) r -- ;
                }else if(nums[l] + nums[i] + nums[r] < 0){
    
    
                    l ++ ;
                }else{
    
    
                    r -- ;
                }
            }
        }
        return res;
    }
};

18. The sum of four numbers (sort + double pointer, the same as the sum of three numbers)

Analysis: time complexity O( n 3 n^{3}n3 ), more troublesome than the addition of four numbers II in the de-duplication processing!
Insert picture description here

class Solution {
    
    
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
    
    
        vector<vector<int>> res;
        int n = nums.size();
        sort(nums.begin(), nums.end());
        for(int i = 0;i < n ; i++ )
            for(int j = i + 1;j < n ;j ++ )
            {
    
    
                // 去重        
                if(i != 0 && nums[i] == nums[i - 1]) break;
                if(j != i + 1 && nums[j] == nums[j - 1]) continue; // 这里是continue 
        
                int l = j + 1,r = n - 1;
                while(l < r)
                {
    
    
                    if(nums[i] + nums[j] + nums[l] + nums[r] == target){
    
    
                        res.push_back({
    
    nums[i], nums[j], nums[l], nums[r]});
                        l ++ ,r -- ;
                        while(l < r && nums[l] == nums[l - 1]) l ++ ;
                        while(l < r && nums[r] == nums[r + 1]) r --; 
                        
                    }else if(nums[i] + nums[j] + nums[l] + nums[r] < target) l ++ ;
                    else r -- ;
                }
            }
        
        return res;
    }
};

Guess you like

Origin blog.csdn.net/weixin_43154149/article/details/112180592