일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 코딩테스트
- HDFS
- 분산
- 분산처리
- Apache Hadoop
- 티스토리챌린지
- Data Engineering
- 하둡
- docker
- leetcode
- 아파치 스파크
- 오블완
- 우선순위큐
- 알고리즘
- 데이터 엔지니어링
- Hadoop
- 이진탐색
- 빅데이터
- 도커
- Apache Spark
- Spark
- 딕셔너리
- Python
- 파이썬
- heapq
- 스파크
- programmers
- 아파치 하둡
- 프로그래머스
- 리트코드
- Today
- Total
래원
[LeetCode] 2563. Count the Number of Fair Pairs - Python 본문
[LeetCode] 2563. Count the Number of Fair Pairs - Python
Laewon Jeong 2024. 11. 13. 15: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
문제 예제
Example 1:
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).
Example 2:
Input: nums = [1,7,9,2,5], lower = 11, upper = 11
Output: 1
Explanation: There is a single fair pair: (2,3).
제한 사항
1 <= nums.length <= 105
nums.length == n
-109 <= nums\[i\] <= 109
-109 <= lower <= upper <= 109
내 풀이
class Solution:
def countFairPairs(self, nums: List[int], lower: int, upper: int) -> int:
def dfs(nums, now, visited, pair, answer, lower, upper):
if len(pair) == 2:
if lower <= now <= upper:
answer += 1
return answer
for i, num in enumerate(nums):
if not visited[i]:
visited[i] = True
pair.append(num)
answer = dfs(nums, now+num, visited, pair, answer, lower, upper)
visited[i] = False
if pair: pair.pop()
return answer
answer = dfs(nums, 0, defaultdict(bool), [], 0, lower, upper)
return answer//2
처음에는 위와 같이 dfs로 접근해서 모든 pair를 탐색하고 조건에 맞으면 answer에 1을 더해주는 코드를 작성했다.
하지만 이 코드는 큰 input 데이터에 대해서 아래 그림과 같이 시간초과가 나는 것을 확인했다.
따라서, 이 문제는 dfs 방식으로 푸는 문제가 아니란 것을 깨닫고, 이것 저것 적어보기 시작했는데, 이진탐색이 떠올랐다.
Input이 [0,1,7,4,4,5]이고 이걸 정렬시켰을 때 [0, 1, 4, 4, 5, 7]이 되니까 각 요소마다 lower를 만족할 수 있는 다른 요소가 있는 위치와 upper를 만족할 수 있는 다른 요소가 있는 위치를 구해 뺀 값을 더해주면 될 것 같았다.
이 위치는 이진탐색 알고리즘으로 쉽게 구할 수 있다. 이를 구현한 코드는 다음과 같다.
def binary_search(nums, n, start, is_left):
left, right = start, len(nums)
while left < right:
mid = (left+right)//2
if nums[mid] < n and is_left:
left = mid+1
elif nums[mid] <= n and not is_left:
left = mid+1
else:
right = mid
return left
class Solution:
def countFairPairs(self, nums: List[int], lower: int, upper: int) -> int:
nums.sort()
n = len(nums)
answer = 0
for i in range(n):
left = binary_search(nums, lower-nums[i], i+1, True)
right = binary_search(nums, upper-nums[i], i+1, False)
answer += right - left
return answer
이렇게 문제를 해결할 수 있었다. 다른 사람의 풀이를 보니 python에는 bisect라는 이진탐색을 지원하는 함수가 있다는 것을 처음 알게되었다. 알아두면 유용할 것 같은데 이진탐색이 필요할 때 한번 써봐야겠다.
'알고리즘 > LeetCode' 카테고리의 다른 글
[LeetCode] 2461. Maximum Sum of Distinct Subarrays With Length K - Python (0) | 2024.11.19 |
---|---|
[LeetCode] 1652. Defuse the Bomb - Python (0) | 2024.11.18 |
[LeetCode] 2064. Minimized Maximum of Products Distributed to Any Store - Python (1) | 2024.11.14 |
[LeetCode] 2070. Most Beautiful Item for Each Query - Python (1) | 2024.11.12 |
[LeetCode] 2601. Prime Subtraction Operation - Python (2) | 2024.11.12 |