1. 程式人生 > 實用技巧 >Leetcode 1577 數的平方等於兩數乘積的方法數

Leetcode 1577 數的平方等於兩數乘積的方法數

Leetcode 1577 數的平方等於兩數乘積的方法數

題目

給你兩個整數陣列 nums1 和 nums2 ,請你返回根據以下規則形成的三元組的數目(型別 1 和型別 2 ):

  • 型別 1:三元組 (i, j, k) ,如果$ nums1[i]2 == nums2[j] * nums2[k] 其中 0 <= i < nums1.length 且 0 <= j < k < nums2.length$
  • 型別 2:三元組 (i, j, k) ,如果 \(nums2[i]2 == nums1[j] * nums1[k] 其中 0 <= i < nums2.length 且 0 <= j < k < nums1.length\)

示例 1:

輸入:nums1 = [7,4], nums2 = [5,2,8,9]
輸出:1
解釋:型別 1:(1,1,2), nums1[1]^2 = nums2[1] * nums2[2] (4^2 = 2 * 8)

示例 2:

輸入:nums1 = [1,1], nums2 = [1,1,1]
輸出:9
解釋:所有三元組都符合題目要求,因為 1^2 = 1 * 1
型別 1:(0,0,1), (0,0,2), (0,1,2), (1,0,1), (1,0,2), (1,1,2), nums1[i]^2 = nums2[j] * nums2[k]
型別 2:(0,0,1), (1,0,1), (2,0,1), nums2[i]^2 = nums1[j] * nums1[k]

示例 3:

輸入:nums1 = [7,7,8,3], nums2 = [1,2,9,7]
輸出:2
解釋:有兩個符合題目要求的三元組
型別 1:(3,0,2), nums1[3]^2 = nums2[0] * nums2[2]
型別 2:(3,0,1), nums2[3]^2 = nums1[0] * nums1[1]

示例 4:

輸入:nums1 = [4,7,9,11,23], nums2 = [3,5,1024,12,18]
輸出:0
解釋:不存在符合題目要求的三元組

提示:

1 <= nums1.length, nums2.length <= 1000
1 <= nums1[i], nums2[i] <= 10^5

思路

利用雜湊表。

首先對第一個陣列的每一個數取平方,然後插入到雜湊表中,如果已經存在那麼就在原來大小上+1.

然後遍歷第二個陣列,取兩個數的乘積去雜湊表裡尋找,直接加上雜湊表中的數值。

這個數值是有意義的,比如上面給出的示例2,

示例 2:

輸入:nums1 = [1,1], nums2 = [1,1,1]
輸出:9
解釋:所有三元組都符合題目要求,因為 1^2 = 1 * 1
型別 1:(0,0,1), (0,0,2), (0,1,2), (1,0,1), (1,0,2), (1,1,2), nums1[i]^2 = nums2[j] * nums2[k]
型別 2:(0,0,1), (1,0,1), (2,0,1), nums2[i]^2 = nums1[j] * nums1[k]

nums1裡只會得到兩個結果是1的值,如果後面遍歷後查詢雜湊表,會只得到“能找到這樣的匹配”的結果。但是如果我們讓數字有意義,存放nums1中平方得到該值的個數,那麼後面遍歷時能得到的就不僅僅是能找到這樣的匹配了,而是“這樣的匹配有n個”,把n加到結果上即可。

注意:

  • int相乘可能會超過int的範圍,這時候要用long,而且要主動轉換型別,否則int*int>int範圍就會直接報錯了。
  • 注意翻轉兩個陣列的順序再找一遍。

程式碼與結果

class Solution {
public:
    int numTriplets(vector<int>& nums1, vector<int>& nums2) {
        return hashAndFind(nums1,nums2) + hashAndFind(nums2,nums1);
    }
private:
    int hashAndFind(vector<int>& nums1, vector<int>& nums2){
        int res = 0;
        map<long, int> mp;
        for(auto& num : nums1){
            ++mp[(long)num*num];
        }
        int n = nums2.size();
        for(int i = 0; i< n-1; ++i){
            for(int j=i+1; j<n; ++j){
                res += mp[(long)nums2[i]*nums2[j]];
            }
        }
        return res;
    }
};

結果(大概是沒啥人做這個題,所以排名靠前