Java solution using sorting. With explanation and comments. 4 ms. Faster than 100%.
Sort both arrays.\n2. Similar to the Two sum we have to find all the pairs that matches to the target. Target is the Square number. \n3. Start with left pointer
1. Sort both arrays.\n2. Similar to the Two sum we have to find all the pairs that matches to the target. Target is the Square number. \n3. Start with left pointer set to 0, and right pointer set to length-1.\n4. Must handle duplicates. \n\t* \te.g. Target: 4, nums = [1,1,4,4]\n\t* \tSo, total 4 pairs with indexes (0,2), (1,2), (0,3), (1,3)\n\t* \twhen left = 0, and right = 3, we found one pair. (0,3)\n\t\t* \tNow before updating left or right pointer, travesre through all values from left+1 to right whose value is same as nums[left]. It will give us the multiplication equals to target.\n\t\t* \tThis way we will find next pair (1,3).\n\t* Decrement right pointer, and reset left pointer.\n4. Repeat this process for all values in both arrays.\n\nRead the code comments for some added optimization.\n\n```\nclass Solution {\n    public int numTriplets(int[] nums1, int[] nums2) {\n        Arrays.sort(nums1);\n        Arrays.sort(nums2);\n        \n        int count = 0;\n        count += triplets(nums1, nums2);\n        count += triplets(nums2, nums1);\n        \n        return count;        \n    }\n    \n    public int triplets(int[] nums1, int[] nums2) {\n        \n\t\tMap<Long, Integer> seen = new HashMap<>();\n        int count = 0;\n        \n        for(int i=0; i<nums1.length; i++) {\n            long sqr = (long) nums1[i] * nums1[i];  //Target Value. Don\'t forget to convert to Long\n            if(seen.containsKey(sqr)) { //If we have already seen the target value, then no need to repeat the process and find the pairs.  \n                count += seen.get(sqr);\n                continue;\n            }\n            \n            int localCount = 0;  //Find the pairs for current Target\n            int left = 0, right = nums2.length-1; \n\t\t\t\n            while(left < right) {  //Similar to Two sum, find all pairs whose multiplication equals to Target\n                if(nums2[left] > sqr)  // For optimization. If the lowest value is larger than target then break the loop.\n                    break;\n                long multiple = (long) nums2[left] * nums2[right];\n                \n                if(sqr == multiple) {\n                    if(nums2[left] == nums2[right]) { //Special Case: when numbers from left to right are same. \n\t\t\t\t\t\tint n = right - left+1;      // In the case the total pairs will be n*(n-1)/2.\n                        localCount += n * (n-1)/2;\n                        break;\n                    }\n                    localCount++;  // Found one pair: Increament the counter.\n                    int newL = left+1;  //To handle duplicates pairs, we will check all numbers from left side. Numbers must be same as the left number for equal multiplication.\n                    for(newL = left+1; newL < right && nums2[newL] == nums2[left]; newL++) {\n                            localCount++;                        \n                    }\n                    right--;\n                    \n                } else if (multiple < sqr)\n                    left++;\n                else\n                    right--;\n            }\n\t\t\t\n\t\t\tcount += localCount;\n            seen.put(sqr, localCount);  //Add the pairs for target value in seen.\n\t\t\t\n        }\n        return count;\n    }\n}\n```\n\n** Thanks to nanwu6805 for optimization suggestion. We do no need to repeat the same process and can use the count. I changed it a bit and instead used hashmap.
[]