리트코드 챌린지 #2
6666 단어 beginnersalgorithmsjavascript
오늘의 문제
오늘의 주제:
Two pointers
ID
이름
어려움
문제
해결책
977
정렬된 배열의 제곱
쉬운
link
link
189
어레이 회전
중간
link
link
283
0 이동
쉬운
link
link
167
Two Sum II - 입력 배열이 정렬됨
중간
link
link
2~5일차 주제는
Two pointers
입니다. 저는 이 단어가 생소하지만 저번에 사용한 이진 검색 방식은 일종의 투 포인터인 것 같습니다.977, 283, 167번 문제는 실제로 매우 쉽고 솔루션이 직관적이기 때문에 건너뛰겠습니다.
189. 배열 회전
문제는 정말 흥미 롭습니다.
슬라이스+연결 또는 끝에서 회전과 같은 일부 간단한 방법은 공간이 너무 많이 듭니다(각각 O(n) 및 O(k)).
O(1) 공간 솔루션을 생각해 내는 데 시간이 좀 걸렸습니다(모두 O(n) 시간이지만).
주요 아이디어는 다음과 같습니다.
nums[0]을 nums[k]로 이동하고 원래 nums[k]를 nums[2*k]로 이동하면 ...(물론 모듈로 n에서) 다시 nums[0으로 돌아옵니다. ] 어느 시점에서. 그러나 경우에 따라 이 주기에는 모든 숫자가 포함되지 않습니다. 보다 정확하게는
0 + m * gcd(n, k)
형식의 인덱스만 포함됩니다. 따라서 동일한 절차를 반복해야 하지만 1 ~ gcd(n, k)
부터 시작합니다.예를 들어 고려하다
n = 9, k = 6
0 -> 6 -> 3 -> 0 -> ...
1 -> 7 -> 4 -> 1 -> ...
2 -> 8 -> 5 -> 2 -> ...
결과 코드:
var rotate = function (nums, k) {
const g = gcd(nums.length, k);
for (let i = 0; i < g; i++) {
let j = i;
let tmp = nums[j];
let next;
while (next != i) {
next = (j + k) % nums.length;
[nums[next], tmp] = [tmp, nums[next]];
j = next;
}
}
};
이 솔루션은 일종의 융통성이 없습니다. 그래서 나는 leetcode 토론을 확인하고 아름다운 마법을 발견했습니다. 핵심 개념은 다음과 같습니다.
rotate(n, k) = reverse(0, n-1) + reverse(0, k-1) + reverse(k, n-1)
예를 들어 고려하다
n = 7, n = 3
[1, 2, 3, 4, 5, 6, 7] // original
-> [7, 6, 5, 4, 3, 2, 1] // reverse(0, 6)
-> [5, 6, 7, 4, 3, 2, 1] // reverse(0, 2)
-> [5, 6, 7, 1, 2, 3, 4] // reverse(3, 6)
이 마법이 어떻게 발견되었는지는 모르겠지만 정말 충격적이었습니다.
추가 문제
오늘 선택한 또 다른 두 개의 포인터 문제는 다음과 같습니다.
ID
이름
어려움
문제
해결책
11
물이 가장 많은 용기
중간
link
link
예상외로 이 문제는 40분 정도 걸렸습니다. 제약 조건에 따르면
n < 10^5
, O(n^2)는 허용되지 않습니다. 따라서 무차별 열거로는 충분하지 않습니다.많은 예를 살펴본 후 면적 공식
(l - r) * Math.min(height[l], height[r])
이 높이의 최소값만 고려한다는 것을 알았습니다. 이 경우 더 작은 높이를 우선시하는 욕심 많은 알고리즘이 유용할 수 있습니다.최종 알고리즘은 다음과 같습니다.
가장 바깥 쪽 쌍에서 시작하여 면적 값을 기록하고 더 큰 높이를 찾을 때까지 작은 쪽을 안쪽으로 축소합니다. 새 영역이 더 크면 레코드를 업데이트하십시오. 그런 다음 두 포인터가 일치할 때까지 단계를 반복해서 반복합니다. 양쪽의 높이가 같으면 한쪽만 축소하면 면적이 절대 커지지 않으므로 동시에 축소해야 합니다.
테두리를 축소할 때마다 컨테이너의 너비가 작아집니다. 따라서 높이를 최대화하는 데 집중하면 됩니다. 그리디 알고리즘은 면적 공식의 속성으로 인해 작동합니다.
복잡성은 O(n) 시간과 O(1) 공간입니다. 테두리 축소 프로세스는 총 n-1번 수행되고 면적 계산은 O(1)이기 때문입니다.
결론
위의 다섯 문제는 마지막 문제의 예상치 못한 난이도로 인해 약 1.5시간이 걸렸습니다. 또한 지난 번 문제들보다 더 어렵습니다. 마지막 알고리즘의 정확성 증명에는 일부 수학적 기술이 필요합니다. 루프 불변. 하지만 이 시리즈는 알고리즘 튜토리얼이 아닙니다. 죄송합니다. 자세한 내용은 건너뛰겠습니다.
이것이 오늘 제 도전입니다. 즐기시기 바랍니다. :)
<-- | | -->
Reference
이 문제에 관하여(리트코드 챌린지 #2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/miccwan/leetcode-practice-2-51pg텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)