leetcode: Maximum Sum Circular Subarray (kadane 알고리즘)
728x90
https://leetcode.com/problems/maximum-sum-circular-subarray/
해당 문제는 kadane 알고리즘 방법으로 접근하여 문제를 해결 하였습니다.
Approach
- Kadane's algorithm을 사용하여 일반적인 최대 부분합을 O(n)에 구합니다.
- 순환하는 경우는 전체 합에서 최소 부분합을 빼서 구합니다.
- 모든 원소가 음수인 경우는 별도로 처리합니다.
시간복잡도: O(n) 공간복잡도: O(1)
- 전체 배열의 합 (total): 5 + (-3) + 5 = 7
- 최소 부분합 (minSum): -3
- 연속된 부분 배열 중 가장 작은 합
- total - minSum = 7 - (-3) = 10
- 이것이 바로 [5,5]를 선택했을 때의 합과 같습니다!
이렇게 되는 이유는:
- 순환 배열에서 양 끝의 원소들을 선택하려면 (예: [5,5])
- 중간에 있는 원소들을 제외해야 합니다 (예: [-3])
- 중간의 원소들을 제외하는 가장 좋은 방법은 "최소 부분합"을 찾아서 제거하는 것입니다
- 따라서 "전체 합 - 최소 부분합"이 순환 배열에서 가능한 최대 부분합이 됩니다
이 방식은 다음과 같은 장점이 있습니다:
- 한 번의 순회로 최소 부분합을 찾을 수 있습니다 (O(n))
- 전체 합도 한 번의 순회로 구할 수 있습니다 (O(n))
- 추가 메모리를 사용하지 않습니다 (O(1))
func maxSubarraySumCircular(nums []int) int {
if len(nums) == 0 {
return 0
}
kadane := func(nums []int, findMax bool) int {
curr := nums[0]
result := nums[0]
for i := 1; i < len(nums); i++ {
if findMax {
curr = max(nums[i], curr+nums[i])
result = max(curr, result)
} else {
curr = min(nums[i], curr+nums[i])
result = min(curr, result)
}
}
return result
}
findMax := kadane(nums, true)
if findMax < 0 {
return findMax
}
totalSum := 0
for _, num := range nums {
totalSum += num
}
findMin := kadane(nums, false)
return max(findMax, totalSum-findMin)
}
728x90
'Algorithm' 카테고리의 다른 글
Leetcode - Gas Station (0) | 2024.03.02 |
---|---|
순열(Permutation) 구하기 with kotlin (0) | 2022.11.26 |
Leet code 3 — Longest Substring Without Repeating Characters (0) | 2022.10.01 |
로또의 최고 순위와 최저 순위 - programmers (golang) (0) | 2021.09.06 |
Go - 부분집합 (MS 인터뷰 문제: DFS 완전탐색) (0) | 2021.09.05 |
댓글
이 글 공유하기
다른 글
-
Leetcode - Gas Station
Leetcode - Gas Station
2024.03.02 -
순열(Permutation) 구하기 with kotlin
순열(Permutation) 구하기 with kotlin
2022.11.26 -
Leet code 3 — Longest Substring Without Repeating Characters
Leet code 3 — Longest Substring Without Repeating Characters
2022.10.01 -
로또의 최고 순위와 최저 순위 - programmers (golang)
로또의 최고 순위와 최저 순위 - programmers (golang)
2021.09.06