반응형
Recent Posts
Notice
Recent Comments
Link
250x250
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

지식창고

[Java] LeetCode 918. Maximum Sum Circular Subarray 본문

Algorithm/Leetcode

[Java] LeetCode 918. Maximum Sum Circular Subarray

junz 2023. 1. 18. 15:12
728x90
반응형

[Java] LeetCode 918. Maximum Sum Circular Subarray

 

문   제 : 

정수형 1차원 배열 nums가 주어진다.

배열의 시작과 끝이 연결되어 원처럼 생겼다고 가정한다.

이 때 부분 집합의 합을 최대로 갖는 값을 구하여라.

 

 

{ 1 <= nums.length <= 3 * 10^4 }

{ -3 * 10^4 <= nums[i] <= 3 * 10^4 }

 

 

Given a circular integer array nums of length n, 
return the maximum possible sum of a non-empty subarray of nums.

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].

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

 

Example )

Input: nums = [1,-2,3,-2]
Output: 3
Explanation: Subarray [3] has maximum sum 3.

//////////////////////////////////////
Input: nums = [-3,-2,-3]
Output: -2
Explanation: Subarray [-2] has maximum sum -2.

 



접   근 : 

배열에서 최대 부분집합의 합을 구하는 알고리즘인 Kadane Algorithm을 사용한다.

원으로 연결되어 있다고 가정하기 때문에 이 부분을 추가해야한다.

 



해   결 : 

Kadane Algorithm을 구현한다.

배열에서의 최대 부분집합의 합을 구한다.

원래 배열의 총합을 total이라고 하자.

배열의 부호를 반전시킨 후 최대 부분집합의 합을 구한다.

그리고 total을 더해준다.

 

둘 중 더 큰 값을 return 해준다.

 


 

Kadane Algorithm을 구현한다.

배열을 처음부터 반복하면서 해당 인덱스 값을 더해줄건지 말건지 결정한다.

public int kadane(int[] nums){
    int max = nums[0];
    int maxSum = nums[0];

    for(int i=1; i<nums.length; i++){
        maxSum = Math.max(maxSum + nums[i], nums[i]);
        max = Math.max(max, maxSum);
    }

    return max;
}

 

 


 

최대 부분배열의 합을 구해준다. (max1)

배열의 부호를 반전시킨 후 최대 부분배열의 합을 구해준다. 그리고 거기에 원래 배열의 총합을 더해준다. (max2)

max1 = kadane(nums); // 최대 부분배열 합

for(int i=0; i<nums.length; i++){
    total += nums[i];
    nums[i] = -nums[i];
}

max2 = kadane(nums) + total; // 부호를 역전한 최대 부분배열 합 + 원래 배열의 총합

 


 

만약 max2가 0이라면 max1을 리턴해준다. 

아니라면 둘 중 큰 값을 리턴해준다. 

 

if(max2 == 0) return max1;

return Math.max(max1, max2);

 

 



결   과  :

class Solution {
    public int maxSubarraySumCircular(int[] nums) {
        int max1, max2, total=0;

        max1 = kadane(nums); // 최대 부분배열 합

        for(int i=0; i<nums.length; i++){
            total += nums[i];
            nums[i] = -nums[i];
        }

        max2 = kadane(nums) + total; // 부호를 역전한 최대 부분배열 합 + 원래 배열의 총합

        if(max2 == 0) return max1;

        return Math.max(max1, max2);
    }

    public int kadane(int[] nums){
        int max = nums[0];
        int maxSum = nums[0];

        for(int i=1; i<nums.length; i++){
            maxSum = Math.max(maxSum + nums[i], nums[i]);
            max = Math.max(max, maxSum);
        }

        return max;
    }
}
728x90
반응형
Comments