๐ ๋ฌธ์
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
๐ซ ์์
Input: nums = [0,1,7,4,4,5], lower = 3, upper = 6
Output: 6
Explanation: There are 6 fair pairs: (0,3), (0,4), (0,5), (1,3), (1,4), and (1,5).
๐ฑ ์ ํ
- 1 <= nums.length <= $10^5$
- nums.length == n
- $-10^9$ <= nums[i] <= $10^9$
- $-10^9$ <= lower <= upper <= $10^9$
๐ ๋ฌธ์ ํ์ด
๋ฌธ์ ๋ฅผ ์์ฝํ์๋ฉด nums์์ i, j ๋ฅผ ๊ณจ๋ผ(i != j) ๋ํ์ ๋ lower ๋ณด๋ค ๊ฐ๊ฑฐ๋ ํฌ๊ณ , upper ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์ ์ง๊ฟ ์๋ฅผ ๊ตฌํ๋ ๋ฌธ์ ์ด๋ค.
์ด์ค for๋ฌธ ๋๋ ค๊ฐ๋ฉฐ ๊ตฌํ๋ฉด $O(n^2)$๋ก ์๊ฐ์ด๊ณผ๊ฐ ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ฉด ์ข ๋ ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํด์ผ ํ๋๋ฐ ์ฌ๊ธฐ์ ๋ ์ค๋ฅด๋ ๊ฒ์ ์ด๋ถํ์์ด๋ค. ์ซ์๋ฅผ ๊ณ ๋ฅผ ๋์๋ ์๋ก ๋ค๋ฅธ ์ซ์๋ง ๊ณ ๋ฅด๋ฉด ๋๋ ๊ฒ์ด์ง ๋ค๋ฅธ ์ถ๊ฐ ์ ํ์ฌํญ์ ์์๋ค.
์ฐ์ nums๋ฅผ ์ ๋ ฌํ๊ณ , nums[i]์ ๋ํด์ lower <= nums[i] + nums[j] <= upper๋ฅผ ๋ง์กฑํ๋ nums[j]๋ฅผ ์ฐพ์์ผ ํ๋ค. ์ด๋ฅผ ๋ถ๋ฆฌํด์ ๋ณด๋ฉด, lower <= nums[i] + nums[j], nums[i] + nums[j] <= upper ๋ก ๋๋ ์ ์๊ฐํ ์ ์๋๋ฐ, ์์ ๋ค์ ๋ฐ๊ฟ๋ณด๋ฉด ๊ฒฐ๊ตญ lower - nums[i] <= nums[j] ์ nums[j] <= upper - nums[i] ๊ฐ ๋๋ค.
lower - nums[i] <= nums[j] ๋ฅผ ๋ง์กฑํ๋ ์ต์ ์ธ๋ฑ์ค j๋ฅผ left ๋ผ๊ณ ํ๊ณ , nums[j] <= upper - nums[i]๋ฅผ ๋ง์กฑํ๋ ์ต๋ ์ธ๋ฑ์ค j๋ฅผ right๋ผ๊ณ ํ์ ๋, right - left + 1์ด ํ์ฌ ์ธ๋ฑ์ค i์ ๋ํด์ lower <= nums[i] + nums[j] <= upper ๋ฅผ ๋ง์กฑํ๋ ๊ฐฏ์๊ฐ ๋๋ค.
์ต์ ์ธ๋ฑ์ค๋ฅผ ์ฐพ๊ธฐ ์ํด์ lowerBound๋ฅผ ์ฌ์ฉํ์๊ณ , ์ต๋ ์ธ๋ฑ์ค๋ฅผ ์ฐพ๊ธฐ ์ํด์ upperBound๋ฅผ ์ฌ์ฉํ์๋ค. ๊ฐ๊ฐ ์ธ๋ฑ์ค๋ ํ์ฌ i ๋ณด๋ค ์ปค์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ฒ์๋ ์ง์ ์ง์ ํด์ฃผ์๋ค.
left๋ right๋ ์ด๋ถํ์์ ์ฌ์ฉํ์ฌ ๊ตฌํ๋ฉด ๊ฐ๊ฐ $O(logN)$ ์ผ๋ก ์ด ๋ฌธ์ ๋ $O(n * logN)$ ์ผ๋ก ํด๊ฒฐํ ์ ์๋ค.
๐ป ์ฝ๋
์ด๋ฒ์๋ go๋ก ๋ฌธ์ ๋ฅผ ํ์ด ๋ณด์๋ค.
func upperBound(nums []int, start int, end int, target int) int {
left := start
right := end
for left <= right {
mid := left + (right-left)/2
if nums[mid] > target {
right = mid - 1
} else {
left = mid + 1
}
}
return right
}
func lowerBound(nums []int, start int, end int, target int) int {
left := start
right := end
for left <= right {
mid := left + (right-left)/2
if nums[mid] < target {
left = mid + 1
} else {
right = mid - 1
}
}
return left
}
func countFairPairs(nums []int, lower int, upper int) int64 {
var res int64 = 0
sort.Ints(nums)
n := len(nums)
for i := 0; i < n; i++ {
left := lowerBound(nums, i+1, n-1, lower-nums[i])
right := upperBound(nums, i+1, n-1, upper-nums[i])
if left <= right {
res += int64(right - left + 1)
}
}
return res
}
๐ ๋ฌธ์ ๋งํฌ
'Problem Solving > ๋ฆฌํธ์ฝ๋' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[LeetCode] 406. Queue Reconstruction by Height (2) | 2024.11.08 |
---|---|
[LeetCode] 3036. Number of Subarrays That Match a Pattern II (0) | 2024.02.11 |
[LeetCode] 380. Insert Delete GetRandom O(1) (1) | 2024.01.21 |
[LeetCode] 1657. Determine if Two Strings Are Close (1) | 2024.01.14 |