548. 將數組分割成和相等的子數組


描述

給定一個有 n 個整數的數組,你需要找到滿足以下條件的三元組 (i, j, k) :

0 < i, i + 1 < j, j + 1 < k < n - 1
子數組 (0, i - 1),(i + 1, j - 1),(j + 1, k - 1),(k + 1, n - 1) 的和應該相等。
這里我們定義子數組 (L, R) 表示原數組從索引為L的元素開始至索引為R的元素。
示例:

輸入: [1,2,1,2,1,2,1]
輸出: True
解釋:
i = 1, j = 3, k = 5.
sum(0, i - 1) = sum(0, 0) = 1
sum(i + 1, j - 1) = sum(2, 2) = 1
sum(j + 1, k - 1) = sum(4, 4) = 1
sum(k + 1, n - 1) = sum(6, 6) = 1

注意:
1 <= n <= 2000。
給定數組中的元素會在 [-1,000,000, 1,000,000] 范圍內。

思路

前綴和(數組和的問題很多都可以用這個方法)加剪枝,關鍵是尋找剪枝的條件:
sum(0,i-1)+sum(i+1,j-1) = sum(j+1,k-1)+sum(k+1,n-1)
=>sum(0,j-1)-nums[i] = sum(j+1,n-1)-nums[k]
=>sum(0,j-1)-sum(j+1,n-1) = nums[i]-nums[k]
=>|sum(0,j-1)-sum(j+1,n-1)| = |nums[i]-nums[k]| <= max-min

bool splitArray(int* nums, int numsSize){
    if(numsSize<7){
        return false;
    }
    int sum_map[numsSize+1];
    memset(sum_map,0,numsSize+1);
    int max=nums[0],min=nums[0];
    for(int i=0;i<numsSize;i++){
        sum_map[i+1]=sum_map[i]+nums[i];
        max=max>nums[i]?max:nums[i];
        min=min<nums[i]?min:nums[i];
    }
    for(int j=3;j<=numsSize-4;j++){
        if(abs(sum_map[j]+sum_map[j+1]-sum_map[numsSize])<=max-min){
            for(int i=1;i<=j-2;i++){
                if(sum_map[i]==sum_map[j]-sum_map[i+1]){
                    for(int k=j+2;k<numsSize-1;k++){
                        if(sum_map[k]-sum_map[j+1]==sum_map[i]&&sum_map[numsSize]-sum_map[k+1]==sum_map[i]){
                            return true;
                        }
                    }
                }
            }
        }
    }
    return false;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM