Leetcode (자바) -53. 그리고 최대 서브

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);
  }

 

게시 된 142 개 원래 기사 · 원 찬양 31 ·은 20000 +를 볼

추천

출처blog.csdn.net/qq_38905818/article/details/104065544