给定一个由N个整数组成的数组arr [] ,任务是打印两个需要删除的数组元素的索引,以便可以将给定的数组拆分为三个相等总和的子数组。如果无法这样做,请打印“ -1” 。
例子:
Input: arr[] = {2, 5, 12, 7, 19, 4, 3}
Output: 2 4
Explanation:
Removing arr[2] and arr[4] modifies arr[] to {2, 5, 7, 4, 3}.
Sum of subarray {arr[0], arr[1]} = 7.
arr[2] = 7.
Sum of subarray {arr[3], arr[4]} = 7.
Input: arr[] = {2, 1, 13, 5, 14}
Output: -1
天真的方法:最简单的方法是生成所有可能的数组元素对,并针对每一对,检查去除这些对是否可以从给定的数组中生成三个相等的子数组。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if array can
// be split into three equal sum
// subarrays by removing two elements
void findSplit(int arr[], int N)
{
for (int l = 1; l <= N - 4; l++) {
for (int r = l + 2; r <= N - 2; r++) {
// Stores sum of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
for (int i = 0; i <= l - 1; i++) {
lsum += arr[i];
}
// Sum of middle subarray
for (int i = l + 1; i <= r - 1; i++) {
msum += arr[i];
}
// Sum of right subarray
for (int i = r + 1; i < N; i++) {
rsum += arr[i];
}
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
cout << l << " " << r << endl;
return;
}
}
}
// If no pair exists, print -1
cout << -1 << endl;
}
// Driver code
int main()
{
// Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = sizeof(arr) / sizeof(arr[0]);
findSplit(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG
{
// Function to check if array can
// be split into three equal sum
// subarrays by removing two elements
static void findSplit(int arr[], int N)
{
for (int l = 1; l <= N - 4; l++)
{
for (int r = l + 2; r <= N - 2; r++)
{
// Stores sum of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
for (int i = 0; i <= l - 1; i++) {
lsum += arr[i];
}
// Sum of middle subarray
for (int i = l + 1; i <= r - 1; i++) {
msum += arr[i];
}
// Sum of right subarray
for (int i = r + 1; i < N; i++) {
rsum += arr[i];
}
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
System.out.println( l + " " + r );
return;
}
}
}
// If no pair exists, print -1
System.out.print(-1 );
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.length;
findSplit(arr, N);
}
}
// This code is contributed by sanjoy_62.
Python3
# Pyhton 3 program for the above approach
# Function to check if array can
# be split into three equal sum
# subarrays by removing two elements
def findSplit(arr, N):
for l in range(1, N - 3, 1):
for r in range(l + 2, N - 1, 1):
# Stores sum of all three subarrays
lsum = 0
rsum = 0
msum = 0
# Sum of left subarray
for i in range(0, l, 1):
lsum += arr[i]
# Sum of middle subarray
for i in range(l + 1, r, 1):
msum += arr[i]
# Sum of right subarray
for i in range(r + 1, N, 1):
rsum += arr[i]
# Check if sum of subarrays are equal
if (lsum == rsum and rsum == msum):
# Print the possible pair
print(l, r)
return
# If no pair exists, print -1
print(-1)
# Driver code
if __name__ == '__main__':
# Given array
arr = [2, 5, 12, 7, 19, 4, 3]
# Size of the array
N = len(arr)
findSplit(arr, N)
# This code is contributed by SURENDRA_GANGWAR.
C#
// C# program for the above approach
using System;
class GFG
{
// Function to check if array can
// be split into three equal sum
// subarrays by removing two elements
static void findSplit(int []arr, int N)
{
for (int l = 1; l <= N - 4; l++)
{
for (int r = l + 2; r <= N - 2; r++)
{
// Stores sum of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
for (int i = 0; i <= l - 1; i++) {
lsum += arr[i];
}
// Sum of middle subarray
for (int i = l + 1; i <= r - 1; i++) {
msum += arr[i];
}
// Sum of right subarray
for (int i = r + 1; i < N; i++) {
rsum += arr[i];
}
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
Console.WriteLine( l + " " + r );
return;
}
}
}
// If no pair exists, print -1
Console.Write(-1 );
}
// Driver Code
public static void Main(string[] args)
{
// Given array
int []arr = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.Length;
findSplit(arr, N);
}
}
// This code is contributed by AnkThon
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
void findSplit(int arr[], int N)
{
// Stores prefix sum array
vector sum(N);
// Copy array elements
for (int i = 0; i < N; i++) {
sum[i] = arr[i];
}
// Traverse the array
for (int i = 1; i < N; i++) {
sum[i] += sum[i - 1];
}
for (int l = 1; l <= N - 4; l++) {
for (int r = l + 2; r <= N - 2; r++) {
// Stores sums of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
cout << l << " " << r << endl;
return;
}
}
}
// If no such pair exists, print -1
cout << -1 << endl;
}
// Driver Code
int main()
{
// Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = sizeof(arr) / sizeof(arr[0]);
findSplit(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG
{
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
static void findSplit(int arr[], int N)
{
// Stores prefix sum array
int []sum = new int[N];
// Copy array elements
for (int i = 0; i < N; i++)
{
sum[i] = arr[i];
}
// Traverse the array
for (int i = 1; i < N; i++)
{
sum[i] += sum[i - 1];
}
for (int l = 1; l <= N - 4; l++) {
for (int r = l + 2; r <= N - 2; r++) {
// Stores sums of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
System.out.print(l+ " " + r +"\n");
return;
}
}
}
// If no such pair exists, print -1
System.out.print(-1 +"\n");
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.length;
findSplit(arr, N);
}
}
// This code is contributed by shikhasingrajput
C#
// C# program for the above approach
using System;
public class GFG
{
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
static void findSplit(int []arr, int N)
{
// Stores prefix sum array
int []sum = new int[N];
// Copy array elements
for (int i = 0; i < N; i++)
{
sum[i] = arr[i];
}
// Traverse the array
for (int i = 1; i < N; i++)
{
sum[i] += sum[i - 1];
}
for (int l = 1; l <= N - 4; l++) {
for (int r = l + 2; r <= N - 2; r++) {
// Stores sums of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
Console.Write(l+ " " + r +"\n");
return;
}
}
}
// If no such pair exists, print -1
Console.Write(-1 +"\n");
}
// Driver Code
public static void Main(String[] args)
{
// Given array
int []arr = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.Length;
findSplit(arr, N);
}
}
// This code is contributed by 29AjayKumar
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
void findSplit(int arr[], int N)
{
// Two pointers l and r
int l = 1, r = N - 2;
int lsum, msum, rsum;
// Stores prefix sum array
vector sum(N);
sum[0] = arr[0];
// Traverse the array
for (int i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
// Two pointer approach
while (l < r) {
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Print split indices if sum is equal
if (lsum == msum and msum == rsum) {
cout << l << " " << r << endl;
return;
}
// Move left pointer if lsum < rsum
if (lsum < rsum)
l++;
// Move right pointer if rsum > lsum
else if (lsum > rsum)
r--;
// Move both pointers if lsum = rsum
// but they are not equal to msum
else {
l++;
r--;
}
}
// If no possible pair exists, print -1
cout << -1 << endl;
}
// Driver Code
int main()
{
// Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = sizeof(arr) / sizeof(arr[0]);
findSplit(arr, N);
return 0;
}
Java
// Java program for the above approach
public class GFG
{
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
static void findSplit(int []arr, int N)
{
// Two pointers l and r
int l = 1, r = N - 2;
int lsum, msum, rsum;
// Stores prefix sum array
int sum[] = new int[N];
sum[0] = arr[0];
// Traverse the array
for (int i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
// Two pointer approach
while (l < r) {
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Print split indices if sum is equal
if (lsum == msum && msum == rsum) {
System.out.println(l + " " + r);
return;
}
// Move left pointer if lsum < rsum
if (lsum < rsum)
l++;
// Move right pointer if rsum > lsum
else if (lsum > rsum)
r--;
// Move both pointers if lsum = rsum
// but they are not equal to msum
else {
l++;
r--;
}
}
// If no possible pair exists, print -1
System.out.println(-1);
}
// Driver Code
public static void main (String[] args)
{
// Given array
int []arr = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.length;
findSplit(arr, N);
}
}
// This code is contributed by AnkThon
Python3
# Python3 program for the above approach
# Function to check if array can
# be split into three equal sum
# subarrays by removing a pair
def findSplit(arr, N) :
# Two pointers l and r
l = 1; r = N - 2;
# Stores prefix sum array
sum = [0]*N;
sum[0] = arr[0];
# Traverse the array
for i in range(1, N) :
sum[i] = sum[i - 1] + arr[i];
# Two pointer approach
while (l < r) :
# Sum of left subarray
lsum = sum[l - 1];
# Sum of middle subarray
msum = sum[r - 1] - sum[l];
# Sum of right subarray
rsum = sum[N - 1] - sum[r];
# Print split indices if sum is equal
if (lsum == msum and msum == rsum) :
print(l,r);
return;
# Move left pointer if lsum < rsum
if (lsum < rsum) :
l += 1;
# Move right pointer if rsum > lsum
elif (lsum > rsum) :
r -= 1;
# Move both pointers if lsum = rsum
# but they are not equal to msum
else :
l += 1;
r -= 1;
# If no possible pair exists, print -1
print(-1);
# Driver Code
if __name__ == "__main__" :
# Given array
arr = [ 2, 5, 12, 7, 19, 4, 3 ];
# Size of the array
N = len(arr);
findSplit(arr, N);
# This code is contributed by AnkThon
输出:
2 4
时间复杂度: O(N 3 )
辅助空间: O(1)
高效的方法:为了优化上述方法,我们的想法是使用Prefix Sum数组技术在恒定时间内查找所有子数组和。请按照以下步骤解决问题:
- 初始化大小为N的向量和以存储数组的前缀和。
- 初始化两个变量,例如l & r,以存储要删除的两个索引,以便将数组拆分为3个相等的子数组。
- 这三个子数组的总和为sum [l – 1] , sum [r – 1] – sum [l]和sum [N – 1] – sum [r] 。
- 使用变量l在[1,N – 4]范围内迭代:
- 使用变量r遍历[l + 2,N – 2]的范围,并检查在任何点上,左子数组之和等于中间子数组之和,右子数组之和,然后打印l和r的值并返回。
- 如果不存在这样的对,则打印-1。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
void findSplit(int arr[], int N)
{
// Stores prefix sum array
vector sum(N);
// Copy array elements
for (int i = 0; i < N; i++) {
sum[i] = arr[i];
}
// Traverse the array
for (int i = 1; i < N; i++) {
sum[i] += sum[i - 1];
}
for (int l = 1; l <= N - 4; l++) {
for (int r = l + 2; r <= N - 2; r++) {
// Stores sums of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
cout << l << " " << r << endl;
return;
}
}
}
// If no such pair exists, print -1
cout << -1 << endl;
}
// Driver Code
int main()
{
// Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = sizeof(arr) / sizeof(arr[0]);
findSplit(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG
{
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
static void findSplit(int arr[], int N)
{
// Stores prefix sum array
int []sum = new int[N];
// Copy array elements
for (int i = 0; i < N; i++)
{
sum[i] = arr[i];
}
// Traverse the array
for (int i = 1; i < N; i++)
{
sum[i] += sum[i - 1];
}
for (int l = 1; l <= N - 4; l++) {
for (int r = l + 2; r <= N - 2; r++) {
// Stores sums of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
System.out.print(l+ " " + r +"\n");
return;
}
}
}
// If no such pair exists, print -1
System.out.print(-1 +"\n");
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.length;
findSplit(arr, N);
}
}
// This code is contributed by shikhasingrajput
C#
// C# program for the above approach
using System;
public class GFG
{
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
static void findSplit(int []arr, int N)
{
// Stores prefix sum array
int []sum = new int[N];
// Copy array elements
for (int i = 0; i < N; i++)
{
sum[i] = arr[i];
}
// Traverse the array
for (int i = 1; i < N; i++)
{
sum[i] += sum[i - 1];
}
for (int l = 1; l <= N - 4; l++) {
for (int r = l + 2; r <= N - 2; r++) {
// Stores sums of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
Console.Write(l+ " " + r +"\n");
return;
}
}
}
// If no such pair exists, print -1
Console.Write(-1 +"\n");
}
// Driver Code
public static void Main(String[] args)
{
// Given array
int []arr = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.Length;
findSplit(arr, N);
}
}
// This code is contributed by 29AjayKumar
输出:
2 4
时间复杂度: O(N 2 )
辅助空间: O(N)
最佳方法:最佳方法是同时使用两点技术和前缀和。请按照以下步骤解决问题:
- 初始化大小为N的向量以存储数组的前缀和。
- 初始化两个变量,例如l & r ,以使用两指针方法遍历数组。
- 遍历数组直到l
或直到三个和都相等: - 如果左子数组的总和大于右子数组的总和,请向右子数组添加一个额外的元素。因此,将r的值减少1 。
- 如果右子数组的总和大于左子数组的总和,则向左子数组添加一个元素。因此,将l增加1 。
- 如果左右两个子数组的总和相等,但不等于中间子数组的总和,则将l增加1 ,将r减少1 。
- 如果不存在这样的对,则打印-1。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
void findSplit(int arr[], int N)
{
// Two pointers l and r
int l = 1, r = N - 2;
int lsum, msum, rsum;
// Stores prefix sum array
vector sum(N);
sum[0] = arr[0];
// Traverse the array
for (int i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
// Two pointer approach
while (l < r) {
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Print split indices if sum is equal
if (lsum == msum and msum == rsum) {
cout << l << " " << r << endl;
return;
}
// Move left pointer if lsum < rsum
if (lsum < rsum)
l++;
// Move right pointer if rsum > lsum
else if (lsum > rsum)
r--;
// Move both pointers if lsum = rsum
// but they are not equal to msum
else {
l++;
r--;
}
}
// If no possible pair exists, print -1
cout << -1 << endl;
}
// Driver Code
int main()
{
// Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = sizeof(arr) / sizeof(arr[0]);
findSplit(arr, N);
return 0;
}
Java
// Java program for the above approach
public class GFG
{
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
static void findSplit(int []arr, int N)
{
// Two pointers l and r
int l = 1, r = N - 2;
int lsum, msum, rsum;
// Stores prefix sum array
int sum[] = new int[N];
sum[0] = arr[0];
// Traverse the array
for (int i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
// Two pointer approach
while (l < r) {
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Print split indices if sum is equal
if (lsum == msum && msum == rsum) {
System.out.println(l + " " + r);
return;
}
// Move left pointer if lsum < rsum
if (lsum < rsum)
l++;
// Move right pointer if rsum > lsum
else if (lsum > rsum)
r--;
// Move both pointers if lsum = rsum
// but they are not equal to msum
else {
l++;
r--;
}
}
// If no possible pair exists, print -1
System.out.println(-1);
}
// Driver Code
public static void main (String[] args)
{
// Given array
int []arr = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.length;
findSplit(arr, N);
}
}
// This code is contributed by AnkThon
Python3
# Python3 program for the above approach
# Function to check if array can
# be split into three equal sum
# subarrays by removing a pair
def findSplit(arr, N) :
# Two pointers l and r
l = 1; r = N - 2;
# Stores prefix sum array
sum = [0]*N;
sum[0] = arr[0];
# Traverse the array
for i in range(1, N) :
sum[i] = sum[i - 1] + arr[i];
# Two pointer approach
while (l < r) :
# Sum of left subarray
lsum = sum[l - 1];
# Sum of middle subarray
msum = sum[r - 1] - sum[l];
# Sum of right subarray
rsum = sum[N - 1] - sum[r];
# Print split indices if sum is equal
if (lsum == msum and msum == rsum) :
print(l,r);
return;
# Move left pointer if lsum < rsum
if (lsum < rsum) :
l += 1;
# Move right pointer if rsum > lsum
elif (lsum > rsum) :
r -= 1;
# Move both pointers if lsum = rsum
# but they are not equal to msum
else :
l += 1;
r -= 1;
# If no possible pair exists, print -1
print(-1);
# Driver Code
if __name__ == "__main__" :
# Given array
arr = [ 2, 5, 12, 7, 19, 4, 3 ];
# Size of the array
N = len(arr);
findSplit(arr, N);
# This code is contributed by AnkThon
输出:
2 4
时间复杂度: O(N)
辅助空间: O(N)