레벨업 일지

[python3/파이썬/자바] leetcode 53. Maximum Subarray 본문

알고리즘/leetcode

[python3/파이썬/자바] leetcode 53. Maximum Subarray

24시간이모자란 2023. 1. 7. 00:04

문제

가장 최대가 되는 연속 부분합 구하기 

https://leetcode.com/problems/maximum-subarray/description/

 

Maximum Subarray - LeetCode

Maximum Subarray - Given an integer array nums, find the subarray with the largest sum, and return its sum.   Example 1: Input: nums = [-2,1,-3,4,-1,2,1,-5,4] Output: 6 Explanation: The subarray [4,-1,2,1] has the largest sum 6. Example 2: Input: nums = [

leetcode.com


풀이

연속 부분합 이라 함은 [ 0 .. n ] 구간의 연속 적인 누적합을 말한다.

[ a .. b ] 구간의 합이 최대가 되는 누적합인데 

PointOfView  : 모든 배열이 음수도 가능하다.  이를테면 [-1,-2] 

즉 양수만 있는 것이 아니다. 그러면 단순히 naive 하게 , O(n^2) 로 2차 순회로 최댓값을 구하는 것을 떠올릴 수 있다. 

최적화를 해 보자면, 모든 구간의 합을 더할 필요는 없다. 

즉 

[ 1 , 2, -4, -5, 2 , -1, 5

다음과 같은 배열이 있을때, [2, -1, 5 ] 구간의 합이 제일 크다. 여기서 2차 순회는 nums[i] 가 1일때. 한번쫙 2일때 한번쫙.. -4는 안되고.... 하는 것보다 . 현재까지 누적합 Sum  변수를 만들어서 O(N) 으로 구해보자. 

 

알고리즘은 다음과 같다.

1. 현재까지 누적합 Sum. 
2. Sum + nextNum  > 0 이면 max값 업데이트 해주면서 계속 더한다. 
3. Sum + nuxtNum <= 0 이면 Sum = 0 으로 초기화를 해준다. 
4. 배열에 양수가 하나도 없으면 예외처리를 한다. 

이런식으로 하면 답을 도출 할 수있다.


코드

자바

class Solution {
    public int maxSubArray(int[] nums) {
        int sum = 0;
        int max = nums[0];
        boolean hasPlus = nums[0] > 0;
        int minusM = hasPlus ? 0 : nums[0];
        
        for(int x : nums){
            if(sum < 0) sum = 0;
            if(sum + x > 0 ){
                sum += x;
                max = Math.max(max, sum);
            }else{
                sum = 0 ;
            }

            if (x > 0){
                hasPlus = true;
            }else{
                minusM = Math.max(minusM, x);
            }
        }
        return hasPlus ? max : minusM;
    }
}

파이썬3

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        s = nums[0]
        m = nums[0]
        there_is_plus = nums[0] > 0

        minus_min = 0 if there_is_plus else nums[0]

        for i in range(1,len(nums)):
            if s < 0 : s =0 
            s = s+nums[i] if s+nums[i] > 0 else 0
            if nums[i] > 0 : 
                there_is_plus = True
            else :
                minus_min = max(minus_min, nums[i])
            m = max(m,s)
        if there_is_plus: return m
        else : return minus_min

 

Comments