nums에게 정수 배열을 감안할 때, 상기 연속하는 서브 어레이 (최소의 요소를 포함하는 서브 어레이)의 최대 수익을 갖는 최대 찾기.
예 :
입력 : [-2,1, 설 포닐, -1,2,1, -5,4],
출력 : 6
명 : 연속 서브 어레이 [4, -1,2,1], 최대 6이었다 .
고급 :
이 솔루션의 O (N)의 복잡성을 구현 한 경우, 분할 및 정복의보다 정교한 사용을 해결하려고합니다.
1 개 아이디어 : 돼지 (동적 프로그래밍)
입력으로서 하나의 어레이를 이용하여 문제의 최대 (또는 최소)의 요소 (또는 합)을 찾기 위해, 그리 디 알고리즘은 선형 시간을 해결하는 하나의 방법이다.
모든 단계는 결국 전 세계적으로 최적의 솔루션, 최상의 옵션을 선택합니다.
알고리즘 :
이 알고리즘은 일반적으로 간단하다 : 각각의 단계에서 배열 및 업데이트를 통과 :
현재 요소
최대 규모의 및 요소의 현재 위치
훨씬 큰 및
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length==1)
return nums[0];
int currentMax=nums[0];
int sumMax=nums[0];
for(int i=1;i<nums.length;i++){
currentMax=Math.max(nums[i],currentMax+nums[i]);
sumMax=Math.max(currentMax,sumMax);
}
return sumMax;
}
}
아이디어 2 : 분할 및 정복
이것은 분할 정복하고 전형적인 실시 예를 참조하여 문제를 해결하고, 유사한 병합 정렬 알고리즘을 사용할 수있다. 다음은 방법의 문제를 해결하기 위해 템플릿입니다 :
기본적인 상황을 정의합니다.
하위 문제와 재귀 적으로 해결 그들에 대한 문제.
순서 문제 아이의 합성 용액은 원래 문제의 용액을 얻었다.
알고리즘 :
최대 서브 어레이가있는 경우 해당 숫자 경우 :
N == 1 경우,이 요소를 반환합니다.
앞 서브 어레이 최대 N / 2 요소 (+ 좌우) 요소 인덱스 left_sum / 2의 왼쪽 부분 배열에있다.
right_sum 우측 서브 어레이가 서브 어레이의 최대 마지막 N / 2의 요소이다.
좌측 서브 어레이 cross_sum을 포함하고있는 (+ 좌우) 최대 인덱스 / 2를 포함한다.
class Solution {
public int crossSum(int[] nums, int left, int right, int p) {
if (left == right) return nums[left];
int leftSubsum = Integer.MIN_VALUE;
int currSum = 0;
for(int i = p; i > left - 1; --i) {
currSum += nums[i];
leftSubsum = Math.max(leftSubsum, currSum);
}
int rightSubsum = Integer.MIN_VALUE;
currSum = 0;
for(int i = p + 1; i < right + 1; ++i) {
currSum += nums[i];
rightSubsum = Math.max(rightSubsum, currSum);
}
return leftSubsum + rightSubsum;
}
public int helper(int[] nums, int left, int right) {
if (left == right) return nums[left];
int p = (left + right) / 2;
int leftSum = helper(nums, left, p);
int rightSum = helper(nums, p + 1, right);
int crossSum = crossSum(nums, left, right, p);
return Math.max(Math.max(leftSum, rightSum), crossSum);
}