📜  将数组拆分为三个子数组,使第一个和第三个子数组的和相等且最大

📅  最后修改于: 2021-10-27 09:12:43             🧑  作者: Mango

给定一个由 N 个整数组成的数组,任务是通过将数组拆分为三个子数组来打印第一个子数组的总和,使得第一个和第三个子数组元素的总和相等且最大。

注意:所有元素必须属于一个子数组,子数组也可以为空。

例子:

方法一

一种简单的方法是检查所有可能的分区并使用前缀和概念来找出分区。给出第一个子数组最大和的分区将是答案。

一种有效的方法如下:

  • 存储N个数字的前缀和和后缀和。
  • 使用 C++ 中的 unordered_map 或Java的Hash-map 散列后缀和的索引。
  • 从数组的开头开始迭代,检查当前索引i之外的后缀数组中是否存在前缀和。
  • 如果是,则检查先前的最大值并相应地更新。

下面是上述方法的实现:

C++
// C++ program for Split the array into three
// subarrays such that summation of first
// and third subarray is equal and maximum
#include 
using namespace std;
 
// Function to return the sum of
// the first subarray
int sumFirst(int a[], int n)
{
    unordered_map mp;
    int suf = 0;
 
    // calculate the suffix sum
    for (int i = n - 1; i >= 0; i--)
    {
        suf += a[i];
        mp[suf] = i;
    }
 
    int pre = 0;
    int maxi = -1;
 
    // iterate from beginning
    for (int i = 0; i < n; i++)
    {
        // prefix sum
        pre += a[i];
 
        // check if it exists beyond i
        if (mp[pre] > i)
        {
            // if greater then previous
            // then update maximum
            if (pre > maxi)
            {
                maxi = pre;
            }
        }
    }
 
    // First and second subarray empty
    if (maxi == -1)
        return 0;
 
    // partition done
    else
        return maxi;
}
 
// Driver Code
int main()
{
    int a[] = { 1, 3, 2, 1, 4 };
    int n = sizeof(a) / sizeof(a[0]);
   
    // Function call
    cout << sumFirst(a, n);
    return 0;
}


Java
// Java program for Split the array into three
// subarrays such that summation of first
// and third subarray is equal and maximum
import java.util.HashMap;
import java.util.Map;
 
class GfG {
 
    // Function to return the sum
    // of the first subarray
    static int sumFirst(int a[], int n)
    {
        HashMap mp = new HashMap<>();
        int suf = 0;
 
        // calculate the suffix sum
        for (int i = n - 1; i >= 0; i--)
        {
            suf += a[i];
            mp.put(suf, i);
        }
 
        int pre = 0, maxi = -1;
 
        // iterate from beginning
        for (int i = 0; i < n; i++)
        {
            // prefix sum
            pre += a[i];
 
            // check if it exists beyond i
            if (mp.containsKey(pre) && mp.get(pre) > i)
            {
                // if greater then previous
                // then update maximum
                if (pre > maxi)
                {
                    maxi = pre;
                }
            }
        }
 
        // First and second subarray empty
        if (maxi == -1)
            return 0;
 
        // partition done
        else
            return maxi;
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        int a[] = { 1, 3, 2, 1, 4 };
        int n = a.length;
       
        // Function call
        System.out.println(sumFirst(a, n));
    }
}
 
// This code is contributed by Rituraj Jain


Python3
# Python3 program for Split the array into three
# subarrays such that summation of first
# and third subarray is equal and maximum
 
# Function to return the sum of
# the first subarray
 
 
def sumFirst(a, n):
    mp = {i: 0 for i in range(7)}
    suf = 0
    i = n - 1
 
    # calculate the suffix sum
    while(i >= 0):
        suf += a[i]
        mp[suf] = i
        i -= 1
 
    pre = 0
    maxi = -1
 
    # iterate from beginning
    for i in range(n):
 
        # prefix sum
        pre += a[i]
 
        # check if it exists beyond i
        if (mp[pre] > i):
 
            # if greater then previous
            # then update maximum
            if (pre > maxi):
                maxi = pre
 
    # First and second subarray empty
    if (maxi == -1):
        return 0
 
    # partition done
    else:
        return maxi
 
 
# Driver Code
if __name__ == '__main__':
    a = [1, 3, 2, 1, 4]
    n = len(a)
     
    # Function call
    print(sumFirst(a, n))
 
# This code is contributed by
# Surendra_Gangwar


C#
// C# program for Split the array into three
// subarrays such that summation of first
// and third subarray is equal and maximum
using System;
using System.Collections.Generic;
 
class GfG {
 
    // Function to return the sum
    // of the first subarray
    static int sumFirst(int[] a, int n)
    {
        Dictionary mp
            = new Dictionary();
        int suf = 0;
 
        // calculate the suffix sum
        for (int i = n - 1; i >= 0; i--)
        {
            suf += a[i];
            mp.Add(suf, i);
            if (mp.ContainsKey(suf))
            {
                mp.Remove(suf);
            }
            mp.Add(suf, i);
        }
 
        int pre = 0, maxi = -1;
 
        // iterate from beginning
        for (int i = 0; i < n; i++)
        {
 
            // prefix sum
            pre += a[i];
 
            // check if it exists beyond i
            if (mp.ContainsKey(pre) && mp[pre] > i)
            {
                // if greater then previous
                // then update maximum
                if (pre > maxi)
                {
                    maxi = pre;
                }
            }
        }
 
        // First and second subarray empty
        if (maxi == -1)
            return 0;
 
        // partition done
        else
            return maxi;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
 
        int[] a = { 1, 3, 2, 1, 4 };
        int n = a.Length;
       
        // Function call
        Console.WriteLine(sumFirst(a, n));
    }
}
 
// This code is contributed by Rajput-Ji


Javascript


C++
// C++ program for Split the array into three
// subarrays such that summation of first
// and third subarray is equal and maximum
#include 
using namespace std;
 
// Function to return the sum of
// the first subarray
int sumFirst(int a[], int n)
{
    // two pointers are initialized
    // one at the front and the other
    // at the back
    int front_pointer = 0;
    int back_pointer = n - 1;
 
    // prefixsum and suffixsum initialized
    int prefixsum = a[front_pointer];
    int suffixsum = a[back_pointer];
 
    // answer variable initialized to 0
    int answer = 0;
 
    while (front_pointer < back_pointer)
    {
        // if the summation are equal
        if (prefixsum == suffixsum)
        {
            // answer updated
            answer = max(answer, prefixsum);
 
            // both the pointers are moved by step
            front_pointer++;
            back_pointer--;
 
            // prefixsum and suffixsum are updated
            prefixsum += a[front_pointer];
            suffixsum += a[back_pointer];
        }
        else if (prefixsum > suffixsum)
        {
            // if prefixsum is more,then back pointer is
            // moved by one step and suffixsum updated.
            back_pointer--;
            suffixsum += a[back_pointer];
        }
        else
        {
            // if prefixsum is less,then front pointer is
            // moved by one step and prefixsum updated.
            front_pointer++;
            prefixsum += a[front_pointer];
        }
    }
 
    // answer is returned
    return answer;
}
 
// Driver code
int main()
{
    int arr[] = { 1, 3, 2, 1, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    cout << sumFirst(arr, n);
 
    // This code is contributed by Arif
}


Java
// Java program for Split the array into three
// subarrays such that summation of first
// and third subarray is equal and maximum
import java.util.*;
 
class GFG{
     
// Function to return the sum of
// the first subarray
public static int sumFirst(int a[], int n)
{
     
    // Two pointers are initialized
    // one at the front and the other
    // at the back
    int front_pointer = 0;
    int back_pointer = n - 1;
  
    // prefixsum and suffixsum initialized
    int prefixsum = a[front_pointer];
    int suffixsum = a[back_pointer];
  
    // answer variable initialized to 0
    int answer = 0;
     
    while (front_pointer < back_pointer)
    {
         
        // If the summation are equal
        if (prefixsum == suffixsum)
        {
             
            // answer updated
            answer = Math.max(answer, prefixsum);
  
            // Both the pointers are moved by step
            front_pointer++;
            back_pointer--;
  
            // prefixsum and suffixsum are updated
            prefixsum += a[front_pointer];
            suffixsum += a[back_pointer];
        }
        else if (prefixsum > suffixsum)
        {
             
            // If prefixsum is more,then back pointer is
            // moved by one step and suffixsum updated.
            back_pointer--;
            suffixsum += a[back_pointer];
        }
        else
        {
             
            // If prefixsum is less,then front pointer is
            // moved by one step and prefixsum updated.
            front_pointer++;
            prefixsum += a[front_pointer];
        }
    }
     
    // answer is returned
    return answer;
} 
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 1, 3, 2, 1, 4 };
    int n = arr.length;
  
    // Function call
    System.out.print(sumFirst(arr, n));
}
}
 
// This code is contributed by divyeshrabadiya07


Python3
# Python3 program for Split the array into three
# subarrays such that summation of first
# and third subarray is equal and maximum
import math
 
# Function to return the sum of
# the first subarray
def sumFirst(a, n):
     
    # Two pointers are initialized
    # one at the front and the other
    # at the back
    front_pointer = 0
    back_pointer = n - 1
     
    # prefixsum and suffixsum initialized
    prefixsum = a[front_pointer]
    suffixsum = a[back_pointer]
     
    # answer variable initialized to 0
    answer = 0
     
    while (front_pointer < back_pointer):
         
        # If the summation are equal
        if (prefixsum == suffixsum):
             
            # answer updated
            answer = max(answer, prefixsum)
 
            # Both the pointers are moved by step
            front_pointer += 1
            back_pointer -= 1
 
            # prefixsum and suffixsum are updated
            prefixsum += a[front_pointer]
            suffixsum += a[back_pointer]
             
        elif (prefixsum > suffixsum):
             
            # If prefixsum is more,then back pointer is
            # moved by one step and suffixsum updated.
            back_pointer -= 1
            suffixsum += a[back_pointer]
        else:
             
            # If prefixsum is less,then front pointer is
            # moved by one step and prefixsum updated.
            front_pointer += 1
            prefixsum += a[front_pointer]
 
    # answer is returned
    return answer
 
# Driver code
arr = [ 1, 3, 2, 1, 4 ]
n = len(arr)
 
# Function call
print(sumFirst(arr, n))
 
# This code is contributed by Stream_Cipher


C#
// C# program for split the array into three
// subarrays such that summation of first
// and third subarray is equal and maximum
using System;
 
class GFG{
     
// Function to return the sum of
// the first subarray
static int sumFirst(int[] a, int n)
{
     
    // Two pointers are initialized
    // one at the front and the other
    // at the back
    int front_pointer = 0;
    int back_pointer = n - 1;
     
    // prefixsum and suffixsum initialized
    int prefixsum = a[front_pointer];
    int suffixsum = a[back_pointer];
   
    // answer variable initialized to 0
    int answer = 0;
     
    while (front_pointer < back_pointer)
    {
         
        // If the summation are equal
        if (prefixsum == suffixsum)
        {
             
            // answer updated
            answer = Math.Max(answer, prefixsum);
             
            // Both the pointers are moved by step
            front_pointer++;
            back_pointer--;
             
            // prefixsum and suffixsum are updated
            prefixsum += a[front_pointer];
            suffixsum += a[back_pointer];
        }
        else if (prefixsum > suffixsum)
        {
             
            // If prefixsum is more,then back pointer is
            // moved by one step and suffixsum updated.
            back_pointer--;
            suffixsum += a[back_pointer];
        }
        else
        {
             
            // If prefixsum is less,then front pointer is
            // moved by one step and prefixsum updated.
            front_pointer++;
            prefixsum += a[front_pointer];
        }
    }
     
    // answer is returned
    return answer;
}
 
// Driver Code
static void Main()
{
    int[] arr = { 1, 3, 2, 1, 4 };
    int n = arr.Length;
     
    // Function call
    Console.WriteLine(sumFirst(arr, n));
}
}
 
// This code is contributed by divyesh072019


Javascript


输出
4

方法二

方法:我们将使用两个指针的概念,一个指针从前面开始,另一个从后面开始。在每次迭代中,比较第一个和最后一个子数组的总和,如果它们相同,则在 answer 变量中更新总和。

算法:

  • front_pointer初始化为 0,将back_pointer初始化为 n-1。
  • prefixsum初始化为arr[ front_pointer ]并将suffixsum 初始化arr[back_pointer]
  • 比较总和。
    如果 prefixsum > suffixsum ,back_pointer 减 1 并且 suffixsum+= arr[ back_pointer ]。
    如果 prefixsum < suffixsum, front_pointer 加 1 并且 prefixsum+= arr[ front_pointer ]
    如果它们相同,则在答案变量中更新总和,并且两个指针都移动一步
    并且prefixsum和suffixsum都相应地更新。
  • 继续上述步骤,直到front_pointer不小于back_pointer。

下面是上述方法的实现:

C++

// C++ program for Split the array into three
// subarrays such that summation of first
// and third subarray is equal and maximum
#include 
using namespace std;
 
// Function to return the sum of
// the first subarray
int sumFirst(int a[], int n)
{
    // two pointers are initialized
    // one at the front and the other
    // at the back
    int front_pointer = 0;
    int back_pointer = n - 1;
 
    // prefixsum and suffixsum initialized
    int prefixsum = a[front_pointer];
    int suffixsum = a[back_pointer];
 
    // answer variable initialized to 0
    int answer = 0;
 
    while (front_pointer < back_pointer)
    {
        // if the summation are equal
        if (prefixsum == suffixsum)
        {
            // answer updated
            answer = max(answer, prefixsum);
 
            // both the pointers are moved by step
            front_pointer++;
            back_pointer--;
 
            // prefixsum and suffixsum are updated
            prefixsum += a[front_pointer];
            suffixsum += a[back_pointer];
        }
        else if (prefixsum > suffixsum)
        {
            // if prefixsum is more,then back pointer is
            // moved by one step and suffixsum updated.
            back_pointer--;
            suffixsum += a[back_pointer];
        }
        else
        {
            // if prefixsum is less,then front pointer is
            // moved by one step and prefixsum updated.
            front_pointer++;
            prefixsum += a[front_pointer];
        }
    }
 
    // answer is returned
    return answer;
}
 
// Driver code
int main()
{
    int arr[] = { 1, 3, 2, 1, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    cout << sumFirst(arr, n);
 
    // This code is contributed by Arif
}

Java

// Java program for Split the array into three
// subarrays such that summation of first
// and third subarray is equal and maximum
import java.util.*;
 
class GFG{
     
// Function to return the sum of
// the first subarray
public static int sumFirst(int a[], int n)
{
     
    // Two pointers are initialized
    // one at the front and the other
    // at the back
    int front_pointer = 0;
    int back_pointer = n - 1;
  
    // prefixsum and suffixsum initialized
    int prefixsum = a[front_pointer];
    int suffixsum = a[back_pointer];
  
    // answer variable initialized to 0
    int answer = 0;
     
    while (front_pointer < back_pointer)
    {
         
        // If the summation are equal
        if (prefixsum == suffixsum)
        {
             
            // answer updated
            answer = Math.max(answer, prefixsum);
  
            // Both the pointers are moved by step
            front_pointer++;
            back_pointer--;
  
            // prefixsum and suffixsum are updated
            prefixsum += a[front_pointer];
            suffixsum += a[back_pointer];
        }
        else if (prefixsum > suffixsum)
        {
             
            // If prefixsum is more,then back pointer is
            // moved by one step and suffixsum updated.
            back_pointer--;
            suffixsum += a[back_pointer];
        }
        else
        {
             
            // If prefixsum is less,then front pointer is
            // moved by one step and prefixsum updated.
            front_pointer++;
            prefixsum += a[front_pointer];
        }
    }
     
    // answer is returned
    return answer;
} 
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 1, 3, 2, 1, 4 };
    int n = arr.length;
  
    // Function call
    System.out.print(sumFirst(arr, n));
}
}
 
// This code is contributed by divyeshrabadiya07

蟒蛇3

# Python3 program for Split the array into three
# subarrays such that summation of first
# and third subarray is equal and maximum
import math
 
# Function to return the sum of
# the first subarray
def sumFirst(a, n):
     
    # Two pointers are initialized
    # one at the front and the other
    # at the back
    front_pointer = 0
    back_pointer = n - 1
     
    # prefixsum and suffixsum initialized
    prefixsum = a[front_pointer]
    suffixsum = a[back_pointer]
     
    # answer variable initialized to 0
    answer = 0
     
    while (front_pointer < back_pointer):
         
        # If the summation are equal
        if (prefixsum == suffixsum):
             
            # answer updated
            answer = max(answer, prefixsum)
 
            # Both the pointers are moved by step
            front_pointer += 1
            back_pointer -= 1
 
            # prefixsum and suffixsum are updated
            prefixsum += a[front_pointer]
            suffixsum += a[back_pointer]
             
        elif (prefixsum > suffixsum):
             
            # If prefixsum is more,then back pointer is
            # moved by one step and suffixsum updated.
            back_pointer -= 1
            suffixsum += a[back_pointer]
        else:
             
            # If prefixsum is less,then front pointer is
            # moved by one step and prefixsum updated.
            front_pointer += 1
            prefixsum += a[front_pointer]
 
    # answer is returned
    return answer
 
# Driver code
arr = [ 1, 3, 2, 1, 4 ]
n = len(arr)
 
# Function call
print(sumFirst(arr, n))
 
# This code is contributed by Stream_Cipher

C#

// C# program for split the array into three
// subarrays such that summation of first
// and third subarray is equal and maximum
using System;
 
class GFG{
     
// Function to return the sum of
// the first subarray
static int sumFirst(int[] a, int n)
{
     
    // Two pointers are initialized
    // one at the front and the other
    // at the back
    int front_pointer = 0;
    int back_pointer = n - 1;
     
    // prefixsum and suffixsum initialized
    int prefixsum = a[front_pointer];
    int suffixsum = a[back_pointer];
   
    // answer variable initialized to 0
    int answer = 0;
     
    while (front_pointer < back_pointer)
    {
         
        // If the summation are equal
        if (prefixsum == suffixsum)
        {
             
            // answer updated
            answer = Math.Max(answer, prefixsum);
             
            // Both the pointers are moved by step
            front_pointer++;
            back_pointer--;
             
            // prefixsum and suffixsum are updated
            prefixsum += a[front_pointer];
            suffixsum += a[back_pointer];
        }
        else if (prefixsum > suffixsum)
        {
             
            // If prefixsum is more,then back pointer is
            // moved by one step and suffixsum updated.
            back_pointer--;
            suffixsum += a[back_pointer];
        }
        else
        {
             
            // If prefixsum is less,then front pointer is
            // moved by one step and prefixsum updated.
            front_pointer++;
            prefixsum += a[front_pointer];
        }
    }
     
    // answer is returned
    return answer;
}
 
// Driver Code
static void Main()
{
    int[] arr = { 1, 3, 2, 1, 4 };
    int n = arr.Length;
     
    // Function call
    Console.WriteLine(sumFirst(arr, n));
}
}
 
// This code is contributed by divyesh072019

Javascript


输出
4

时间复杂度: O(n)
辅助空间: O(1)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程