How would we go about testing all combinations of subarrays in a array where length of each subarray is equal to P times the sum of subarray elements.
A brief example: Edit:
A = [2,-1,3,0,1,2,1] , P =2
Desired result:
[2,-1] , [0,1]
Edit Constraint :
N represents number of elements in an array
1 <= N <= 1e5
-1000 <= P <= 1000
|A[i]| <= 1e6
What kind of problem set(for eg:NP-hard?) does these kind of questions fall into ? Language : C#
For every index in the inner loop update sum = sum + array[j]If the sum is equal to the given sum then print the subarray. For every index in the inner loop update sum = sum + array[j] If the sum is equal to the given sum then print the subarray.
How do you find continuous sub array whose sum is equal to a given number in Java? Iterate through the array. At each element add the next n elements one by one, when the sum equals to the required value print the sub array.
1 Traverse the array from start to end. 2 From every index start another loop from i to the end of array to get all subarray starting from i, keep a varibale sum to calculate the sum. 3 For every index in inner loop update sum = sum + array [j] 4 If the sum is equal to the given sum then print the subarray.
2. Hashing We can also use hashing to find subarrays with the given sum in an array by using a map of lists or a multimap for storing the end index of all subarrays having a given sum. The idea is to traverse the given array and maintain the sum of elements seen so far.
How to find contiguous subarray of integers in an array from n arrays such that the sum of elements of such contiguous subarrays is minimum 0 In an array, find an optimized algorithm for finding sum of lengths of longest subarray with current element being the highest in the subarray
Algorithm: 1 Traverse the array from start to end. 2 From every index start another loop from i to the end of array to get all subarray starting from i, keep a varibale sum to calculate the sum. 3 For every index in inner loop update sum = sum + array [j] 4 If the sum is equal to the given sum then print the subarray.
This problem falls in P. Here's an O(n)
solution.
Let's do some algebra with prefix sums:
j - i = p * (prefix_sum_j - prefix_sum_i)
j - i = p * prefix_sum_j - p * prefix_sum_i
j - p * prefix_sum_j = i - p * prefix_sum_i
p * prefix_sum_j - j = p * prefix_sum_i - i
JavaScript code with testing against brute force.
const f = (nums, p) =>
nums.reduce(([map, sum, answer], val, i) => {
const newSum = sum + val;
answer += p * newSum == i + 1;
answer += map[p * newSum - i] || 0;
map[p * newSum - i] = (map[p * newSum - i] || 0) + 1;
return [map, newSum, answer];
}, [{}, 0, 0])[2];
console.log('Input: [2,-1,3,0,1,2,1], 2')
console.log('Output: ' + f([2,-1,3,0,1,2,1], 2));
function bruteForce(A, p){
let result = 0;
for (let windowSize=1; windowSize<=A.length; windowSize++){
for (let start=0; start<A.length-windowSize+1; start++){
let sum = 0;
for (let end=start; end<start+windowSize; end++)
sum += A[end];
if (p * sum == windowSize)
result += 1;
}
}
return result;
}
var numTests = 500;
var n = 20;
var m = 20;
var pRange = 10;
console.log('\nTesting against brute force...')
for (let i=0; i<numTests; i++){
const A = new Array(n);
for (let j=0; j<n; j++)
A[j] = Math.floor(Math.random() * m) * [1, -1][Math.floor(Math.random()*2)];
const p = Math.floor(Math.random() * pRange) * [1, -1][Math.floor(Math.random()*2)];
_f = f(A, p);
_brute = bruteForce(A, p);
//console.log(String([_f, _brute, p, JSON.stringify(A)]));
if (_f != _brute){
console.log('MISMATCH!');
console.log(p, JSON.stringify(A));
console.log(_f, _brute);
break;
}
}
console.log('Done testing.')
In case it helps readers, the function, f
, as a for
loop could look like:
function f(A, p){
const seen = {}; // Map data structure
let sum = 0;
let result = 0;
for (let i=0; i<A.length; i++){
sum += A[i];
result += p * sum == i + 1; // Boolean evaluates to 1 or 0
result += seen[p * sum - i] || 0;
seen[p * sum - i] = (seen[p * sum - i] || 0) + 1;
}
return result;
}
My (first) attempt at C# code:
using System;
using System.Collections.Generic;
public class Solution{
static int f(int[] A, int p){
var seen = new Dictionary<int, int>();
int sum = 0;
int result = 0;
for (int i=0; i<A.Length; i++){
sum += A[i];
result += Convert.ToInt32( p * sum == i + 1 );
int key = p * sum - i;
if (seen.ContainsKey(key)){
result += seen[key];
seen[key] += 1;
} else {
seen[key] = 1;
}
}
return result;
}
public static void Main(){
int[] A = new int[7]{2, -1, 3, 0, 1, 2, 1};
int p = 2;
Console.WriteLine(f(A, p));
}
}
I tried to solve this problem using dynamic programming. In my solution I have used 2 nested for loops for making the dp matrix so it should have time complexity of O(n^2)
(not counting the 3 nested for loops used to print the solution). Since this problem can be solved using brute force method as well as using dynamic programming in polynomial time it has P complexity.
using System;
public class Program
{
public static void Main()
{
int n = 7;
int p = 2;
int[, ] arr = new int[n + 1, n + 1];
int[] nums = new int[]{2, -1, 3, 0, 1, 2, 1};
for (int i = 1; i <= n; i++)
{
for (int j = i; j <= n; j++)
{
arr[i, j] = arr[i - 1, j - 1] + nums[j - 1];
}
}
for (int j = 0; j <= n; j++)
{
for (int k = 0; k <= n; k++)
{
Console.Write(string.Format("{0} ", arr[j, k]));
}
Console.Write(Environment.NewLine);
}
Console.Write(Environment.NewLine + Environment.NewLine);
for (int i = 1; i <= n; i++)
{
Console.WriteLine(string.Format("For length {0}: ", i));
for (int j = i; j <= n; j++)
{
if (p * arr[i, j] == i)
{
Console.Write(string.Format("{0} {1}: ", (j - i + 1), j));
for (int k = j - i + 1; k <= j; k++)
{
Console.Write(string.Format("{0},", nums[k - 1]));
}
Console.Write(Environment.NewLine);
}
}
Console.Write(Environment.NewLine);
}
Console.Write(Environment.NewLine);
}
}
you can test this code on dotnetfiddle (this is the first c# code I have ever written so maybe some more optimizations could be done in code).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With