Skip to content

Commit d992d0f

Browse files
committed
Maximum sub circular subarray
1 parent 04abcd2 commit d992d0f

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# 918. Maximum sub circular subarray
2+
# Topics: 'Array', 'Dynamic Programming', 'Queue', 'Monotonic Queue', 'Divide And Conquer'
3+
# Level: 'Medium'
4+
5+
# Given a circular integer array nums of length n, return the maximum possible sum of a non-empty subarray of nums.
6+
7+
# A circular array means the end of the array connects to the beginning of the array. Formally, the next element of nums[i] is nums[(i + 1) % n] and the previous element of nums[i] is nums[(i - 1 + n) % n].
8+
9+
# A subarray may only include each element of the fixed buffer nums at most once. Formally, for a subarray nums[i], nums[i + 1], ..., nums[j], there does not exist i <= k1, k2 <= j with k1 % n == k2 % n.
10+
11+
12+
13+
# Example 1:
14+
15+
# Input: nums = [1,-2,3,-2]
16+
# Output: 3
17+
# Explanation: Subarray [3] has maximum sum 3.
18+
19+
# Example 2:
20+
21+
# Input: nums = [5,-3,5]
22+
# Output: 10
23+
# Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10.
24+
25+
# Example 3:
26+
27+
# Input: nums = [-3,-2,-3]
28+
# Output: -2
29+
# Explanation: Subarray [-2] has maximum sum -2.
30+
31+
32+
33+
# Constraints:
34+
35+
# n == nums.length
36+
# 1 <= n <= 3 * 104
37+
# -3 * 104 <= nums[i] <= 3 * 104
38+
39+
from typing import List
40+
41+
# class Solution:
42+
# def maxSubarraySumCircular(self, nums: List[int]) -> int:
43+
# total = nums[0]
44+
# curmax = maxsubarray = nums[0]
45+
# curmin = minsubarray = nums[0]
46+
47+
# for i in range(1, len(nums)):
48+
# x = nums[i]
49+
# curmax = max(x, curmax + x)
50+
# maxsubarray = max(maxsubarray, curmax)
51+
# curmin = min(x, curmin + x)
52+
# minsubarray = min(minsubarray, curmin)
53+
# total += x
54+
# if maxsubarray < 0:
55+
# return maxsubarray
56+
# return max(maxsubarray, (total - minsubarray))
57+
58+
59+
# O(n**2)
60+
class Solution:
61+
def maxSubarraySumCircular(self, nums: List[int]) -> int:
62+
length = len(nums)
63+
maxsubarray = 0
64+
for start in range (length):
65+
id = start
66+
curmax = 0
67+
while True:
68+
curmax += nums[id]
69+
curmax = max(curmax, 0)
70+
maxsubarray = max(maxsubarray, curmax)
71+
id = (id+1)%length
72+
if id == start:
73+
break
74+
if maxsubarray == 0:
75+
maxsubarray = max(nums)
76+
return maxsubarray
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from max_circular_subarr import Solution
2+
3+
def test_maxSubarraySumCircular():
4+
solution = Solution()
5+
6+
# Example 1: Simple case, max is single element
7+
assert solution.maxSubarraySumCircular([1, -2, 3, -2]) == 3
8+
9+
# Example 2: Wrapping case - classic circular advantage
10+
assert solution.maxSubarraySumCircular([5, -3, 5]) == 10
11+
12+
# Example 3: All negative numbers
13+
assert solution.maxSubarraySumCircular([-3, -2, -3]) == -2
14+
15+
# Single element
16+
assert solution.maxSubarraySumCircular([5]) == 5
17+
assert solution.maxSubarraySumCircular([-5]) == -5
18+
19+
# Two elements
20+
assert solution.maxSubarraySumCircular([1, 2]) == 3
21+
assert solution.maxSubarraySumCircular([-1, -2]) == -1
22+
23+
# All positive numbers - should take entire array
24+
assert solution.maxSubarraySumCircular([1, 2, 3, 4]) == 10
25+
26+
# Wrapping gives better result than non-wrapping
27+
assert solution.maxSubarraySumCircular([8, -1, -1, -1, 8]) == 16 # Take both 8s
28+
29+
# Non-wrapping is better
30+
assert solution.maxSubarraySumCircular([1, -2, 3, -2, 5]) == 7 # [3, -2, 5]
31+
32+
# Mix of positive and negative
33+
assert solution.maxSubarraySumCircular([3, -1, 2, -1]) == 4 # Entire array
34+
assert solution.maxSubarraySumCircular([3, -2, 2, -3]) == 3 # Either single 3 or [2, -3, 3]
35+
36+
# Large positive at ends, negative in middle
37+
assert solution.maxSubarraySumCircular([5, -3, 5, -3, 5]) == 12 # Wrap around
38+
39+
# Edge case: zeros
40+
assert solution.maxSubarraySumCircular([0, 0, 0]) == 0
41+
assert solution.maxSubarraySumCircular([-1, 0, -1]) == 0
42+
43+
# Large array pattern
44+
assert solution.maxSubarraySumCircular([1, -1, 1, -1, 1]) == 2 # Wrapping
45+
46+
print("All tests passed!")
47+
48+
if __name__ == "__main__":
49+
test_maxSubarraySumCircular()

0 commit comments

Comments
 (0)