ACM준비/LeetCode
2563. Count the Number of Fair Pairs
조규현15
2024. 11. 13. 21:56
반응형
2563. Count the Number of Fair Pairs
Solved
Medium
Topics
Companies
Hint
Given a 0-indexed integer array nums of size n and two integers lower and upper, return the number of fair pairs.
A pair (i, j) is fair if:
0 <= i < j < n, and
lower <= nums[i] + nums[j] <= upper
접근
lower, upper 값 사이에서 pair ( x + y ) 값으로 구성 가능한 조합의 갯수를 찾아야 합니다.
i, j 각각 순회를 돌면서 답을 찾는 방법은 O ( N ^ 2 ) 을 사용하며 시간 초과가 발생합니다.
sort 를 사용하여 O ( N * logN )
i 번째 element 를 사용하여 나머지 j 번째 element 는 lower, upper 내 index 차이로 갯수를 계산합니다.
코드
/**
* @param {number[]} nums
* @param {number} lower
* @param {number} upper
* @return {number}
*/
var countFairPairs = function (nums, lower, upper) {
// sort
nums.sort((a, b) => a - b);
var len = nums.length;
var pairs = 0;
for (var i = 0; i < len - 1; i++) {
var p = nums[i];
var min = lower - p, max = upper - p;
var min_i = i + 1, max_i = len - 1;
// invalid case
if (max < nums[min_i] || nums[max_i] < min) continue;
// find lower bound
var min_n = find_bound(min_i, max_i, min, true);
// find upper bound
var max_n = find_bound(min_i, max_i, max, false);
pairs += (max_n - min_n) + 1;
}
return pairs;
function find_bound(i, j, v, is_lower) {
var left = i, right = j;
// binary search
while (left <= right) {
var mid = Math.floor((left + right) / 2);
var mid_n = nums[mid];
// found
if (mid_n == v) {
if (is_lower) {
// slice when same value
for (var k = mid - 1; k >= i; k--) {
if (nums[k] == v) {
mid = k;
} else {
break;
}
}
} else {
// slice when same value
for (var k = mid + 1; k <= j; k++) {
if (nums[k] == v) {
mid = k;
} else {
break;
}
}
}
return mid;
}
else if (mid_n > v) {
right = mid - 1;
}
else {
left = mid + 1;
}
}
// fail to find
if (is_lower) {
// set lower
return nums[left] >= v ? left : left + 1;
}
else {
// set upper
return nums[right] <= v ? right : right - 1;
}
}
};
반응형