We will find a way, we always have.

-interstellar

Problem Solving/๋ฆฌํŠธ์ฝ”๋“œ

[LeetCode] 2563. Count the Number of Fair Pairs

Redddy 2024. 11. 13. 22:46

๐Ÿ”ˆ ๋ฌธ์ œ

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
}

 

๐Ÿ”— ๋ฌธ์ œ๋งํฌ