当前位置: 首页 > 知识库问答 >
问题:

在长度等于 P * (元素之和) 的数组中查找子数组

蓬兴国
2023-03-14

我们将如何测试数组中每个子数组的长度等于子数组元素之和的P倍的所有子数组组合。

一个简短的示例:编辑:

 A = [2,-1,3,0,1,2,1] , P =2

期望的结果:

  1. 长度=2,P*元素之和=1。子序列是[2,-1],[0,1]

编辑约束:

N represents number of elements in an array
1 <= N <= 1e5
-1000 <= P <= 1000
|A[i]| <= 1e6

这些问题属于什么样的问题集(例如:NP-hard?)?语言:C#

共有2个答案

章振
2023-03-14

我试图使用动态规划来解决这个问题。在我的解决方案中,我使用了2个嵌套for循环来制作dp矩阵,因此它的时间复杂度应该为O(n^2)(不包括用于打印解决方案的3个嵌套for循环)。由于这个问题可以使用蛮力方法以及在多项式时间中使用动态规划来解决,因此它具有P复杂度。

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);
    }
}

您可以在dotnetfiddle上测试此代码(这是我编写的第一个c#代码,因此可能可以在代码中进行更多优化)。

松英喆
2023-03-14

这个问题属于P。这里有一个<code>O(n)

让我们用前缀和做一些代数:

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代码与暴力测试。

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.')
 类似资料:
  • 我正在尝试解决这个算法问题: https://dunjudge.me/analysis/problems/469/ 为了方便起见,我总结了下面的问题陈述。 给定一个长度为 ( 多数元素定义为发生的元素 时限:1.5s 例如: 如果给定的数组是[1,2,1,2,3,2], 答案是5,因为从位置1到5 (0索引)的长度为5的子数组[2,1,2,3,2]具有出现为3的数字2 首先想到的是一个明显的强力(

  • 问题内容: NumPy具有有效的功能/方法来标识对象中非零元素的索引。什么是最有效的方式来获得该元素的索引 做 具有零值? 问题答案: numpy.where()是我的最爱。

  • 如何加快以下问题陈述的执行速度?我有一个正确的解决方案,通过每一个测试的小输入。但是,它超过了较大输入的时间限制。我当前的实现是数组大小的二次型。 你的答案应该是基于1的,这意味着数组的第一个位置是1而不是0。 实施

  • 问题内容: 快速找到整数数组总和的最简单(最佳)方法是什么?我有一个称为倍数的数组,我想知道倍数的总和。 问题答案: 这是我能找到的最简单/最短的方法。 Swift 3和Swift 4: 斯威夫特2: 更多信息: 这使用了Array的reduce方法(在此处提供文档),该方法允许您“通过递归应用所提供的闭包将元素的集合减少到单个值”。我们给它0作为初始值,然后本质上给闭包赋值。当然,我们可以将其简

  • 在swift中查找整数数组和的最简单(最好)方法是什么?我有一个叫做multiples的数组,我想知道multiples的和。