Java Binary Search
Notable issues:\n1. type cast to long BEFORE min max\n2. be aware of whether the binary search end is inclusive or not\n3. be aware the count/index update is ha
Notable issues:\n1. type cast to long BEFORE min max\n2. be aware of whether the binary search end is inclusive or not\n3. be aware the count/index update is happening in which if clause to confirm it is the largest value have k count less than it or smallest\n\n```\n\n\nclass Solution {\n    int m;\n    int n;\n    int[] nums1;\n    int[] nums2;\n    \n    public long kthSmallestProduct(int[] n1, int[] n2, long k) {\n        this.nums1 = n1.length < n2.length? n1: n2;\n        this.nums2 = n1.length < n2.length? n2: n1;\n        \n        m = nums1.length;\n        n = nums2.length;\n        // Do binary search on product value range\n        long l = Math.min(Math.min((long)nums1[m-1]*nums2[n-1], (long)nums1[0]*nums2[0]), Math.min((long)nums1[0]*nums2[n-1], (long)nums2[0]*nums1[m-1]));\n        long r = Math.max(Math.max((long)nums1[m-1]*nums2[n-1], (long)nums1[0]*nums2[0]), Math.max((long)nums1[0]*nums2[n-1], (long)nums2[0]*nums1[m-1]));\n        long res = -1;\n        \n        while(l <= r) {\n            long mid = l + (r-l)/2;\n            long count = countTillMidVal(mid);\n\n            if(count < k) {\n                l = mid+1;\n            } else {\n                res = mid;\n                r = mid-1;\n            }\n        }\n        \n        return res;\n    }\n    \n    private long countTillMidVal(long val) {\n        long count = 0;\n        \n        for(int num: nums1) {\n            // if num > 0, product order is the same as nums2\n            // if nums < 0, product order is reverse as nums2\n            long c = 0;\n            if(num < 0) {\n                c = getCountNums2Reverse(val, num);\n            } else {\n                c = getCountNums2(val, num);\n            }\n            count += c;\n        }\n        \n        return count;\n    }\n    \n    private long getCountNums2(long val, long num1){\n        int l = 0;\n        int r = n - 1;\n        long count = 0;\n        \n        while(l <= r) {\n            int mid = l + (r-l)/2;\n            \n            if(nums2[mid]*num1 <= val) {\n                count = mid+1;\n                l = mid+1;\n            } else {\n                r = mid-1;\n            }\n        }\n        \n        return count;\n    }\n    \n    private long getCountNums2Reverse(long val, long num1) {\n        int l = 0;\n        int r = n - 1;\n        long count = 0;\n        \n        while(l <= r) {\n            int mid = l + (r-l)/2;\n            \n            if(nums2[mid]*num1 > val) {\n                l = mid+1;\n            } else {\n                count = n-mid;\n                r = mid-1;\n            }\n        }\n        \n        return count; \n    }\n}\n```
[]