"LeetCode" - Hash

Today's topic explanation is mainly about the topic explanation of the knowledge point of hashing.


Table of contents

(1) The missing first positive integer

(2) Two numbers that appear only once in the array

1. Direct method

2. Hash

(3) The most points on the straight line


(1) The missing first positive integer

The link is as follows: missing first positive integer

Topic display:

Topic analysis:

Analyzing the topic, we know the following points:

1. If there are negative numbers in the array, we ignore the processing of negative numbers, that is, only judge the missing first positive integer in the case of positive numbers;

2. For an array with a length of n and no repeated numbers, after traversing the array, there will be two situations:

  •  ① If the elements in the array appear between 1 and n, then we can know that the missing number is n+1;
  • ② On the contrary, if the elements in the array are missing between 1~n, then the missing number is the number between 1~n. If this is the case. We only need to use the hash table to determine whether each element has appeared.

specific methods:

  • Step 1 : First, you need to create a hash table to record the numbers that appear in the array.
  • step 2 : Traverse the array from the beginning and record the number of times the numbers appear in the array;
  • step 3 : Then check whether there is this number in the hash table, if not, it means that it is the first positive integer missing from the array

Code display:

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        unordered_map<int, int> tmp;
        for (auto& e : nums) 
        {
            if (e > 0) 
                tmp[e]++;
        }

        for (int i = 1; i <= nums.size() + 1; i++) {
            if (tmp[i] == 0) 
                return i;
        }
        return 0;
    }
};

Performance analysis:

 

  • Time complexity: O(n). The first time to traverse the array, record the number of occurrences of the number is O(n), and the second worst time to traverse from 1 to n is O(n), so the time complexity is O(n).
  • Space complexity: O(n). The hash table records n unique elements with a length of n, so the space complexity is O(n).

(2) Two numbers that appear only once in the array

Here's the link: Two numbers that appear only once in an array

 Topic display:

 Topic analysis:

First of all, the meaning of this question is relatively simple. For this question, we can either use hashing or not. Both methods can make this question. Next, I will introduce both methods to you.

1. Direct method

Specific thoughts:

  1. Do it directly, in fact, the idea is also very simple. First of all, we can sort the array first, which is a very critical step;
  2. Secondly, for the sorted array, we can know that the same numbers must be next to each other, so we can use this to judge it.

 specific methods:

  • step 1 : The first is to sort the elements in the array;
  • step 2 : Traverse the array from the beginning, and find out that the two consecutive numbers are different;
  • step 3 : If two consecutive numbers are the same, then we only need to jump back two positions from the current position to continue searching

Code display:

class Solution {
public:
    vector<int> FindNumsAppearOnce(vector<int>& array) {
        // write code here
        sort(array.begin(),array.end());
        vector<int>tmp;
        int size=array.size();
        for(int i=0; i<size;++i )
        {
            if(array[i] == array[i+1])
                i++;
            else
                tmp.push_back(array[i]);
        }
        return tmp;
    }
};

2. Hash

Specific thoughts:

  1. Since there are two numbers that only appear once, we count the number of occurrences of each number, and use the hash table to quickly access its frequency value according to the key value to achieve the topic requirements.

 specific methods:

  • step 1 : First, sort the elements in the array;
  • step 2 : Traverse the array from the beginning, and use the hash table to count the frequency of each number;
  • Step 3 : Then traverse the array again, compare the hash table, find two numbers with a frequency of 1, and return to achieve

Code display:

class Solution {
public:
    vector<int> FindNumsAppearOnce(vector<int>& array) {
        // write code here
        sort(array.begin(), array.end());
        unordered_map<int, int> tmp;
        vector<int> res;

        for(auto& e : array)
            ++tmp[e];

         //再次遍历数组
        for(int i = 0; i < array.size(); i++)
        {
             //找到频率为1的两个数
            if(tmp[array[i]] == 1)
                res.push_back(array[i]);
        }
            
        return res;
    }
};

Performance analysis:

  • Time complexity: O(n), where n is the length of the array, and each element of the array is traversed twice
  • Space complexity: O(n), the length of the hash table should be (n−2)/2

(3) The most points on the straight line

The link is as follows: 149. Most points on a straight line

 Topic display:

 

 Topic analysis:

The violent solution to this problem is to enumerate straight lines by arbitrarily citing two points, but its time complexity has reached O(N^3), so I won’t introduce too much here;

So how can we optimize it? Let us take the following picture as an example to show you the idea:

Notice:

  • When calculating the slope, if you switch to floating point, there will be precision problems, so we switch to fractions to operate 

 specific methods:

  • Step 1 : When the total number of points is less than or equal to 2, we only need to use a straight line to connect all the points in series, and then we can directly return the total number of points;
  • step 2 : Traverse the array from the beginning and enumerate the center points;
  • Step 3 : Then use the center point to calculate the slope of the slope with other points, and calculate the maximum number. It can be realized by repeating the above operations;

 Code display:

class Solution {
public:
    int maxPoints(vector<vector<int>>& points) {
        int n = points.size();
        //当结点数小于2时,直接返回即可
        if (n < 2) 
            return n;
        int ans = 0;
        //枚举中心店
        for (int i = 0; i < n; i++) {
            //定义哈希表来统计每个斜率的数量
            unordered_map<string, int> tmp;
            //定义Count用来来表示最大的数量
            int Count = 0;
            //枚举剩余点,因为i之前的已经枚举过了,所以才 i+1开始
            for (int j = i + 1; j < n; j++) {
                //获取两点的坐标
                int x1 = points[i][0] ,y1 = points[i][1];
                int x2 = points[j][0] ,y2 = points[j][1];
                //计算斜率
                string key = clac(x1,x2,y1,y2);
                tmp[key]++;
                //更新Count
                Count = max(Count, tmp[key]);
            }
            //一个中心点完成后更新结果
            ans = max(ans, Count+1);
        }
        return ans;
    }
    string clac(int x1, int x2, int y1, int y2)
    {
        //计算横纵坐标的差值,注意记得加绝对值
        int index=abs(x1-x2);
        int indey=abs(y1-y2);
        //最大公约数
        int val=gcd(index, indey);
        //拼接
        string key=to_string (indey / val) + "_" + to_string (index / val);
        //斜率为负,拼接一个 -号
        if((x1 < x2 && y1 > y2) || (x1 > x2 && y1 < y2))
            return "-" + key;

        return key;
    }
};

Performance analysis:

  • Time complexity: O(n^2*logn), where n is the length of the array, enumerating the center point requires O(N), and slope grouping also requires O(N), and requires O(logN) for the greatest common divisor, so The time complexity is O(n^2logn)
  • Space complexity: O(n), because a hash table is required to record, so the space complexity is O(N).


At this point, the explanation of the three questions about the hash table is over. Hope it helps everyone, see you next time! ! !

Guess you like

Origin blog.csdn.net/m0_56069910/article/details/130578193