diff --git a/data_structures/arrays/max_subarray_circular.py b/data_structures/arrays/max_subarray_circular.py new file mode 100644 index 000000000000..cf67ddc53765 --- /dev/null +++ b/data_structures/arrays/max_subarray_circular.py @@ -0,0 +1,63 @@ + +def max_subarray_circular(nums: list[int]) -> int: + """ + Find the maximum possible sum of a subarray in a circular array. + + Args: + nums: List of integers representing the circular array + + Returns: + Maximum sum possible considering the array as circular + + Examples: + >>> max_subarray_circular([1, -2, 3, -2]) + 3 + >>> max_subarray_circular([5, -3, 5]) + 10 + >>> max_subarray_circular([-3, -2, -3]) + -2 + """ + if not nums: + return 0 + + # Case 1: Get the maximum sum using Kadane's algorithm + def kadane(arr): + curr_sum = max_sum = arr[0] + for num in arr[1:]: + curr_sum = max(num, curr_sum + num) + max_sum = max(max_sum, curr_sum) + return max_sum + + # Case 1: The maximum sum without wrapping + max_straight = kadane(nums) + + # If all numbers are negative, return the maximum straight sum + if max_straight < 0: + return max_straight + + # Case 2: The maximum sum with wrapping + # This can be found by subtracting the minimum sum subarray from total sum + total = sum(nums) + # Invert the array and find the maximum sum to get the minimum sum + max_inverted = kadane([-x for x in nums]) + max_wrapped = total + max_inverted # Adding because we inverted the numbers + + return max(max_straight, max_wrapped) + + +if __name__ == "__main__": + import doctest + doctest.testmod() + +""" +This module implements an algorithm to find the maximum sum of a subarray in a circular array. +A circular array means the array can wrap around itself. + +For example: +[1, -2, 3, -2] -> Maximum sum is 3 +[5, -3, 5] -> Maximum sum is 10 because [5, 5] is possible with wrapping +[-3, -2, -3] -> Maximum sum is -2 + +Time Complexity: O(n) +Space Complexity: O(1) +""" \ No newline at end of file diff --git a/data_structures/arrays/sliding_window_maximum.py b/data_structures/arrays/sliding_window_maximum.py new file mode 100644 index 000000000000..78df4e508260 --- /dev/null +++ b/data_structures/arrays/sliding_window_maximum.py @@ -0,0 +1,84 @@ +""" +This module implements an algorithm to find the maximum element in all possible +windows of size k in an array using a deque for O(n) time complexity. + +For example: +[1, 3, -1, -3, 5, 3, 6, 7], k=3 -> [3, 3, 5, 5, 6, 7] +Window position Max +--------------- ----- +[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 + +Time Complexity: O(n) +Space Complexity: O(k) +""" + +from collections import deque +from typing import List + + +def max_sliding_window(nums: List[int], k: int) -> List[int]: + """ + Find maximum elements in all possible windows of size k. + + Args: + nums: List of integers + k: Size of the sliding window + + Returns: + List of maximum elements from each window + + Examples: + >>> max_sliding_window([1, 3, -1, -3, 5, 3, 6, 7], 3) + [3, 3, 5, 5, 6, 7] + >>> max_sliding_window([1], 1) + [1] + >>> max_sliding_window([1, -1], 1) + [1, -1] + >>> max_sliding_window([1, 2, 3, 4], 4) + [4] + """ + if not nums or k <= 0: + return [] + if k == 1: + return nums + + result = [] + # Deque will store indices of potential maximum values + window = deque() + + + for i in range(k): + + while window and nums[i] >= nums[window[-1]]: + window.pop() + window.append(i) + + + for i in range(k, len(nums)): + # First element in deque is the largest in previous window + result.append(nums[window[0]]) + + # Remove elements outside current window + while window and window[0] <= i - k: + window.popleft() + + # Remove smaller elements from back + while window and nums[i] >= nums[window[-1]]: + window.pop() + + window.append(i) + + # Add maximum element of last window + result.append(nums[window[0]]) + + return result + + +if __name__ == "__main__": + import doctest + doctest.testmod() \ No newline at end of file