알고리즘 일기장 | LeetCode 239. 슬라이딩 창 최대 값
11082 단어 leetcode
배열 nums 를 지정 합 니 다. k 크기 의 미끄럼 창 이 배열 의 맨 왼쪽 에서 배열 의 맨 오른쪽 으로 이동 합 니 다.미끄럼 창 k 에 있 는 숫자 만 볼 수 있 습 니 다.슬라이딩 창 은 매번 오른쪽으로 한 분만 이동 합 니 다.
슬라이딩 창의 최대 값 을 되 돌려 줍 니 다.
예시:
: nums = [1,3,-1,-3,5,3,6,7], k = 3
: [3,3,5,5,6,7]
:
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
주의:
k 가 항상 유효 하 다 고 가정 할 수 있 습 니 다. 1 ≤ k ≤ 입력 배열 의 크기 이 고 입력 배열 이 비어 있 지 않 습 니 다.
진급:
당신 은 선형 시간 복잡 도 내 에서 이 문 제 를 해결 할 수 있 습 니까?
분석 해답
이것 은
로 표 시 된 제목 으로 얼핏 보면 선형 복잡 도와 배열 내용 의 동태 적 인 증감 이 있 는 것 을 발견 할 수 있다.이 문제 에 대응 하 는 라벨 은
이기 때문에 우 리 는 먼저 더미 로 해결 하 는 것 을 고려 합 니 다.최대 더 미 를 유지 하고 오른쪽으로 한 칸 씩 이동 할 때마다 최신 값 을 더 미 를 만 든 다음 최대 값 을 꺼 내 현재 창 에 있 는 지 판단 합 니 다.우 리 는 쓰레기 휴지통 으로 추가 계산 기 를 도입 할 수 있 습 니 다. 오른쪽으로 이동 할 때마다 가장 왼쪽 값 은 창 을 떠 납 니 다. 카운터 에서 이 값 의 수 를 하나 더 하면 휴지통 에 이 값 이 하나 더 있 음 을 나타 냅 니 다.그리고 최대 치 를 꺼 낼 때 휴지통 의 계수 가 0 인지, 0 이 아 닌 지 판단 하면 현재 이 최대 치 는 버 려 진 것 이 고 사용 할 수 없 음 을 나타 낸다. 해당 값 이 휴지통 에서 0 이 아 닐 때 까지 다음 최대 치 를 계속 꺼 내야 한다.이런 방법 은 한 번 에 옮 겨 다 니 기만 하면 되 지만 크기 가 * * k * 인 더 미 를 유지 해 야 한다. 매번 쌓 이 고 쌓 이 는 평균 시간 은 logk
이기 때문에 총 소모 시간 은 실제 O(Nlogk)
이다.비록 효율 이 좀 떨 어 졌 지만 직관 적 인 편 이다. 코드 는 다음 과 같다.class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
import heapq
from collections import defaultdict
if not nums:
return []
nums = [-1 * x for x in nums]
counter = defaultdict(int)
windows = nums[:k]
res = []
heapq.heapify(windows)
res.append(-1 * windows[0])
counter[nums[0]] += 1
for i in range(len(nums) - k):
heapq.heappush(windows, nums[i + k])
min_num = windows[0]
while counter[min_num] > 0:
counter[min_num] -= 1
heapq.heappop(windows)
min_num = windows[0]
res.append(-1 * min_num)
counter[nums[i + 1]] += 1
return res
효율 을 한층 높이 기 위해 서 는 창문 이 미 끄 러 질 때 무슨 일이 일 어 났 는 지 더욱 세밀 하 게 살 펴 볼 수 있다.우선 긍정 적 인 점 은 이전 창 에서 가장 왼쪽 값 을 제거 해 야 합 니 다.새로 추 가 된 창의 값 에 대해 a 로 기록 합 니 다. 창 에 작은 값 이 있다 면 이 창 부터 창의 최대 값 은 이 값 이 아 닐 것 입 니 다. 따라서 창 에 남 은 모든 값 이 a 보다 작 지 않 을 때 까지 창 에서 제거 할 수 있 습 니 다.이런 방법 에 따라 창 안의 임의의 시간 에 남 은 값 은 반드시 단 조 롭 고 점차 줄 어드 는 서열 일 것 이다. 우 리 는 쌍 단 대기 열 을 통 해 이런 조작 을 실현 할 수 있다.코드 구현 은 다음 과 같 습 니 다.
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
from collections import deque
res = []
q = deque()
for idx, v in enumerate(nums):
if len(q) > 0 and q[0] <= idx - k:
t = q.popleft()
while len(q) > 0 and nums[q[-1]] < v:
q.pop()
q.append(idx)
if idx >= k - 1:
res.append(nums[q[0]])
return res
이러한 해법 에서 모든 요 소 는 최대 두 번 방문 되 고 매번 방문 할 때마다 상수 작업 이기 때문에 복잡 도 는
O(N)
로 제어 할 수 있다.제출 한 결 과 를 보면 시간 소모 도 이전 방법 보다 확실히 좋다.다만 상대 적 으로 전체 과정 에 대한 심도 있 는 분석 이 필요 하기 때문에 이해 하기 어 려 울 수도 있다.또 질문 이 있 으 면 댓 글 에 댓 글 을 달 아 소통 할 수 있 습 니 다.오늘 의 나 눔 은 여기까지 입 니 다. 나중에 뵙 겠 습 니 다.
이상 은 본문의 모든 내용 입 니 다. 이 글 을 좋아 하신 다 면 친구 들 에 게 공유 해 주 십시오.
읽 어 주 셔 서 감사합니다. 즐 거 운 생활 되 세 요!
작자: 샤 오미 형 2019 - 03 - 21
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
0부터 시작하는 LeetCode Day8 「1302. Deepest Leaves Sum」해외에서는 엔지니어의 면접에 있어서 코딩 테스트라고 하는 것이 행해지는 것 같고, 많은 경우, 특정의 함수나 클래스를 주제에 따라 실장한다고 하는 것이 메인이다. 빠른 이야기가 본고장에서도 행해지고 있는 것 같은 코...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.