给定一个由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
Javascript
Yes
Yes
No