숫자 목록과 다른 값 k가 주어진다고 가정합니다. 이번에는 모든 인접 요소 간의 절대 차이가 최대 k인 가장 긴 부분 수열의 길이를 찾는 것이 우리의 작업입니다.
따라서 입력이 nums =[5, 6, 2, 1, −6, 0, −1, k =4와 같으면 출력은 6이 됩니다.
이 문제를 해결하기 위해 다음 단계를 따릅니다. −
-
update() 함수를 정의합니다. 이것은 i, x
가 걸립니다. -
나는 :=나는 + n
-
i가 0이 아닌 동안 수행
-
segtree[i] :=segtree[i]의 최대값, x
-
나는 :=나는 / 2
-
-
query() 함수를 정의합니다. 이것은 i, j가 걸릴 것입니다
-
ans :=−무한대
-
나는 :=나는 + n
-
j :=j + n + 1
-
i
-
i mod 2가 1과 같으면
-
ans :=최대 ans, segtree[i]
-
나는 :=나는 + 1
-
-
j mod 2가 1과 같으면
-
j :=j − 1
-
ans :=최대 ans, segtree[j]
-
-
나는 :=나는 / 2
-
j :=j / 2
-
-
반환
-
이제 주 기능에서 다음을 수행하십시오. -
-
숫자 =[5, 6, 2, 1, -6, 0, -1]
-
k =4
-
n =2의 거듭제곱(((숫자)의 길이 + 1)의 대수 밑 2
-
세그먼트 트리 :=[0] * 100000
-
snums :=목록 번호 정렬
-
index :=(snums)의 각 인덱스 i와 요소 x에 대해 x:i인 컬렉션을 만듭니다.
-
답변 :=0
-
숫자의 각 x에 대해 수행
-
lo :=snum에서 가장 왼쪽 위치를 반환합니다. 여기서 (x − k)는 정렬된 순서를 유지하면서 삽입할 수 있습니다.
-
hi :=(snums에서 가장 왼쪽 위치, 여기서 (x + k)는 정렬된 순서를 유지하면서 삽입할 수 있음) − 1
-
count :=쿼리(lo, hi)
-
업데이트(인덱스[x], 개수 + 1)
-
ans :=ans의 최대값, 개수 + 1
-
-
반환
이해를 돕기 위해 다음 구현을 살펴보겠습니다. −
예시
import math, bisect class Solution: def solve(self, nums, k): n = 2 ** int(math.log2(len(nums) + 1) + 1) segtree = [0] * 100000 def update(i, x): i += n while i: segtree[i] = max(segtree[i], x) i //= 2 def query(i, j): ans = −float("inf") i += n j += n + 1 while i < j: if i % 2 == 1: ans = max(ans, segtree[i]) i += 1 if j % 2 == 1: j −= 1 ans = max(ans, segtree[j]) i //= 2 j //= 2 return ans snums = sorted(nums) index = {x: i for i, x in enumerate(snums)} ans = 0 for x in nums: lo = bisect.bisect_left(snums, x − k) hi = bisect.bisect_right(snums, x + k) − 1 count = query(lo, hi) update(index[x], count + 1) ans = max(ans, count + 1) return ans ob = Solution() print(ob.solve([5, 6, 2, 1, −6, 0, −1], 4))
입력
[5, 6, 2, 1, −6, 0, −1], 4
출력
6