넘치게 채우기
[LeetCode] 2563. Count the Number of Fair Pairs 본문
leetcode - Count the Number of Fair Pairs
문제 유형: 정렬, 이진탐색, 투 포인터
문제 난이도: Medium
문제
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
n짜리 크기의 0-indexed의 배열 nums와 두 정수 lower와 upper가 주어집니다.
fair한 pair들의 개수를 구하시오.
pair (i, j)는 fair하기 위해, 0 <= i < j < n이고, lower <= nums[i] + nums[j] <= upper 여야 합니다.
풀이
우선, 배열을 정렬해준다.
배열을 정렬해도 되는 이유는, i, j의 의미가 그저 상이한 인덱스를 골라서 페어를 만들면 된다는 의미이기 때문이다.
그리고, 이진탐색을 사용할 것이다.
정렬된 배열에서 두 개의 인덱스를 찾을 것이다.
우선 둘 다 i보다 커야 하고,
하나는 nums[i]와 합해져서 lower를 겨우 넘는 nums[lb]가 되어야 하고,
다른 하나는, nums[i]와 합해져서 upper이내로 들어오는 nums[rb]가 되어야 한다.
그러고, lb <= rb관계이면, i기준, i와 짝지을 수 있는 인덱스는 rb - lb + 1개이다.
lb와 rb를 각각 lower_bound()와 upper_bound() -1로 구한다.
i로 순차적으로 배열을 순회하면서 가능한 쌍들의 개수를 누적해주면 된다.
i입장에서 작지 않은 수들과 쌍을 매번 만드는 것이다.
코드
C++
#pragma GCC optimize("O3", "unroll-loops");
static const int __ = [](){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
return 0;
}();
class Solution {
public:
long long countFairPairs(vector<int>& nums, int lower, int upper) {
int n = nums.size();
sort(nums.begin(), nums.end());
long long ans = 0;
for(int i = 0; i < n; ++i) {
int t1 = lower - nums[i];
int t2 = upper - nums[i];
int lb = lower_bound(nums.begin()+i + 1, nums.end(), t1) - nums.begin();
int rb = upper_bound(nums.begin()+i + 1, nums.end(), t2) - nums.begin() - 1;
if(lb <= rb) ans += rb - lb + 1;
}
return ans;
}
};
'PS > LeetCode' 카테고리의 다른 글
[LeetCode] 1574. Shortest Subarray to be Removed to Make Array Sorted (0) | 2024.11.15 |
---|---|
[LeetCode] 2064. Minimized Maximum of Products Distributed to Any Store (0) | 2024.11.14 |
[LeetCode] 2070. Most Beautiful Item for Each Query (0) | 2024.11.12 |
[LeetCode] 2601. Prime Subtraction Operation (0) | 2024.11.11 |
[LeetCode] 3097. Shortest Subarray With OR at Least K II (0) | 2024.11.10 |