给定一个由N个正整数组成的数组arr [] ,以及由范围[L,R]组成的一些查询,任务是查找给定索引范围内的子数组是否可以分为两个非连续的相邻部分。零长度和相等的总和。
例子:
Input: arr[] = {1, 1, 2, 3}, q[] = {{0, 1}, {1, 3}, {1, 2}}
Output:
Yes
Yes
No
q[0]: The sub-array can be split into {1}, {1}.
q[1]: The sub-array can be split into {1, 2}, {3}.
q[2]: The sub-array can’t be split into two equal segments.
Input: arr[] = {2, 1, 3, 4, 1, 2}, q[] = {{0, 5}, {1, 3}}
Output:
No
Yes
一个简单的解决方案是遍历整个范围并计算范围的总和。然后,我们将再次遍历整个数组。我们将总结从索引“ L”开始的元素。如果在任何步骤上我们发现当前总和是范围总和的一半,则可以将范围代表的子数组分成两个相等的一半。使用这种方法最多可能需要O(n)时间来回答查询。
更好的解决方案是使用前缀和数组。首先,我们创建arr的前缀和数组p_arr 。现在,使用’p_arr’,我们可以确定O(1)时间中’L’到’R’范围内所有元素的总和。一旦有了我们的总和,我们需要确定是否存在从L到R-1的索引“ i”,以使原始数组的L到i之间的所有数字之和为范围之和的一半。为此,我们可以简单地将所有值插入无序映射中的前缀和数组’p_arr’中。
If the value of sum is even and p_arr[l-1] + sum/2 exists in the map, the array can be split into two segments of equal sum.
因此,回答查询的时间复杂度变为O(1)。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to find the required prefix sum
void prefixSum(int* p_arr, int* arr, int n)
{
p_arr[0] = arr[0];
for (int i = 1; i < n; i++)
p_arr[i] = arr[i] + p_arr[i - 1];
}
// Function to hash all the values of prefix
// sum array in an unordered map
void hashPrefixSum(int* p_arr, int n, unordered_set& q)
{
for (int i = 0; i < n; i++)
q.insert(p_arr[i]);
}
// Function to check if a range
// can be divided into two equal parts
void canDivide(int* p_arr, int n,
unordered_set& q, int l, int r)
{
// To store the value of sum
// of entire range
int sum;
if (l == 0)
sum = p_arr[r];
else
sum = p_arr[r] - p_arr[l - 1];
// If value of sum is odd
if (sum % 2 == 1) {
cout << "No" << endl;
return;
}
// To store p_arr[l-1]
int beg = 0;
if (l != 0)
beg = p_arr[l - 1];
// If the value exists in the map
if (q.find(beg + sum / 2) != q.end())
cout << "Yes" << endl;
else
cout << "No" << endl;
}
// Driver code
int main()
{
int arr[] = { 1, 1, 2, 3 };
int n = sizeof(arr) / sizeof(arr[0]);
// prefix-sum array
int p_arr[n];
prefixSum(p_arr, arr, n);
// Map to store the values of prefix-sum
unordered_set q;
hashPrefixSum(p_arr, n, q);
// Perform queries
canDivide(p_arr, n, q, 0, 1);
canDivide(p_arr, n, q, 1, 3);
canDivide(p_arr, n, q, 1, 2);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG {
// Function to find the required prefix sum
static void prefixSum(int[] p_arr, int[] arr, int n)
{
p_arr[0] = arr[0];
for (int i = 1; i < n; i++)
p_arr[i] = arr[i] + p_arr[i - 1];
}
// Function to q all the values of prefix
// sum array in an unordered map
static void qPrefixSum(int[]p_arr, int n, HashSetq)
{
for (int i = 0; i < n; i++)
q.add(p_arr[i]);
}
// Function to check if a range
// can be divided into two equal parts
static void canDivide(int[] p_arr, int n,
HashSetq, int l, int r)
{
// To store the value of sum
// of entire range
int sum;
if (l == 0)
sum = p_arr[r];
else
sum = p_arr[r] - p_arr[l - 1];
// If value of sum is odd
if (sum % 2 == 1) {
System.out.println("No");
return;
}
// To store p_arr[l-1]
int beg = 0;
if (l != 0)
beg = p_arr[l - 1];
// If the value exists in the map
if(q.contains(beg + sum / 2) && (beg + sum / 2)!=(int)q.toArray()[ q.size()-1 ] )
System.out.println("Yes");
else
System.out.println("No");
}
// Driver code
public static void main(String[] args) {
int arr[] = { 1, 1, 2, 3 };
int n = arr.length;
// prefix-sum array
int p_arr[] = new int[n];
prefixSum(p_arr, arr, n);
// Map to store the values of prefix-sum
HashSet q = new HashSet<>();
qPrefixSum(p_arr, n, q);
// Perform queries
canDivide(p_arr, n, q, 0, 1);
canDivide(p_arr, n, q, 1, 3);
canDivide(p_arr, n, q, 1, 2);
}
}
// This code contributed by Rajput-Ji
Python3
# Python3 implementation of the approach
# Function to find the required prefix Sum
def prefixSum(p_arr, arr, n):
p_arr[0] = arr[0]
for i in range(1, n):
p_arr[i] = arr[i] + p_arr[i - 1]
# Function to hash all the values of
# prefix Sum array in an unordered map
def hashPrefixSum(p_arr, n, q):
for i in range(n):
q[p_arr[i]] = 1
# Function to check if a range
# can be divided into two equal parts
def canDivide(p_arr, n, q, l, r):
# To store the value of Sum
# of entire range
Sum = 0
if (l == 0):
Sum = p_arr[r]
else:
Sum = p_arr[r] - p_arr[l - 1]
# If value of Sum is odd
if (Sum % 2 == 1):
print("No")
return
# To store p_arr[l-1]
beg = 0
if (l != 0):
beg = p_arr[l - 1]
# If the value exists in the map
if (beg + Sum // 2 in q.keys()):
print("Yes")
else:
print("No")
# Driver code
arr = [1, 1, 2, 3]
n = len(arr)
# prefix-Sum array
p_arr = [0 for i in range(n)]
prefixSum(p_arr, arr, n)
# Map to store the values
# of prefix-Sum
q = dict()
hashPrefixSum(p_arr, n, q)
# Perform queries
canDivide(p_arr, n, q, 0, 1)
canDivide(p_arr, n, q, 1, 3)
canDivide(p_arr, n, q, 1, 2)
# This code is contributed
# by mohit kumar
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find the required prefix sum
static void prefixSum(int[] p_arr, int[] arr, int n)
{
p_arr[0] = arr[0];
for (int i = 1; i < n; i++)
p_arr[i] = arr[i] + p_arr[i - 1];
}
// Function to q all the values of prefix
// sum array in an unordered map
static void qPrefixSum(int[]p_arr, int n, HashSetq)
{
for (int i = 0; i < n; i++)
q.Add(p_arr[i]);
}
// Function to check if a range
// can be divided into two equal parts
static void canDivide(int[] p_arr, int n,
HashSetq, int l, int r)
{
// To store the value of sum
// of entire range
int sum;
if (l == 0)
sum = p_arr[r];
else
sum = p_arr[r] - p_arr[l - 1];
// If value of sum is odd
if (sum % 2 == 1)
{
Console.WriteLine("No");
return;
}
// To store p_arr[l-1]
int beg = 0;
if (l != 0)
beg = p_arr[l - 1];
// If the value exists in the map
if(q.Contains(beg + sum / 2) )
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 1, 1, 2, 3 };
int n = arr.Length;
// prefix-sum array
int []p_arr = new int[n];
prefixSum(p_arr, arr, n);
// Map to store the values of prefix-sum
HashSet q = new HashSet ();
qPrefixSum(p_arr, n, q);
// Perform queries
canDivide(p_arr, n, q, 0, 1);
canDivide(p_arr, n, q, 1, 3);
canDivide(p_arr, n, q, 1, 2);
}
}
// This code has been contributed by 29AjayKumar
Yes
Yes
No