Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 从N个整数数组中选择有序三元组的不同方法_Algorithm_Permutation_Dynamic Programming - Fatal编程技术网

Algorithm 从N个整数数组中选择有序三元组的不同方法

Algorithm 从N个整数数组中选择有序三元组的不同方法,algorithm,permutation,dynamic-programming,Algorithm,Permutation,Dynamic Programming,给定一个由n个整数组成的数组,我想找到选择有序三元组的方法。例如 A = [1, 2, 1, 1] different ways are (1, 2, 1), (1, 1, 1) and (2, 1, 1) so the answer will be 3. for A = [2, 2, 1, 2, 2] different ways are (1, 2, 2), (2, 1, 2), (2, 2, 1) and (2, 2, 2) so the answer will be 4 in thi

给定一个由n个整数组成的数组,我想找到选择有序三元组的方法。例如

A = [1, 2, 1, 1]
different ways are  (1, 2, 1), (1, 1, 1) and (2, 1, 1)
so the answer will be 3.

for A = [2, 2, 1, 2, 2]
different ways are (1, 2, 2), (2, 1, 2), (2, 2, 1) and (2, 2, 2)
so the answer will be 4 in this case
如果所有的数字都是唯一的,那么我提出了一个循环

f(n) = f(n-1) + ((n-1) * (n-2))/2
where f(3) = 1 and f(2) = f(1) = 0

当数字重复时,我遇到了麻烦。这需要在O(n)时间和O(n)空间中解决。

大小为idx的数组中唯一有序集的数量的动态规划关系为:

DP[集合大小][idx]=DP[集合大小][idx-1]+DP[集合大小-1][idx-1]-DP[集合大小-1][last_idx[A[idx]-1]

因此,要计算idx元素数组中大小LEN的有序唯一集的数量:

  • 取可以从idx-1元素数组创建的有序、唯一的大小LEN集的数量
  • 添加可通过将元素idx添加到大小LEN-1的有序唯一集的末尾来形成的有序唯一集的数量
  • 不要重复计数。减去可通过将元素idx的上一次出现添加到大小LEN-1的有序唯一集的末尾来形成的有序唯一集的数量
这是因为我们在遍历数组时总是对唯一集进行计数。对唯一集进行计数是基于唯一集之前的元素计数

所以,从1号开始,然后是2号,然后是3号,以此类推

对于唯一的、有序的常量大小LEN集,“我的函数”需要O(LEN*N)内存和O(LEN*N)时间。您应该能够重用DP数组,将内存减少到一个独立于LEN,O(constant*N)的常量

下面是函数

    static int answer(int[] A) {
    // This example is for 0 <= A[i] <= 9.  For an array of arbitrary integers, use a proper
    //   HashMap instead of an array as a HashMap. Alternatively, one could compress the input array
    //   down to distinct, consecutive numbers. Either way max memory of the last_idx array is O(n).
    //   This is left as an exercise to the reader.
    final int MAX_INT_DIGIT = 10;
    final int SUBSEQUENCE_LENGTH = 3;
    int n = A.length;

    int[][] dp = new int[SUBSEQUENCE_LENGTH][n];
    int[] last_idx = new int[MAX_INT_DIGIT];
    Arrays.fill(last_idx, -1);

    // Init dp[0] which gives the number of distinct sets of length 1 ending at index i
    dp[0][0] = 1;
    last_idx[A[0]] = 0;

    for (int i = 1; i < n; i++) {
        if (last_idx[A[i]] == -1) {
            dp[0][i] = dp[0][i - 1] + 1;
        } else {
            dp[0][i] = dp[0][i - 1];
        }
        last_idx[A[i]] = i;
    }

    for (int ss_len = 1; ss_len < SUBSEQUENCE_LENGTH; ss_len++) {
        Arrays.fill(last_idx, -1);
        last_idx[A[0]] = 0;
        for (int i = 1; i < n; i++) {
            if (last_idx[A[i]] <= 0) {
                dp[ss_len][i] = dp[ss_len][i - 1] + dp[ss_len-1][i - 1];
            } else {
                dp[ss_len][i] = dp[ss_len][i - 1] + dp[ss_len-1][i - 1] - dp[ss_len-1][last_idx[A[i]] - 1];
            }
            last_idx[A[i]] = (i);
        }
    }

    return dp[SUBSEQUENCE_LENGTH-1][n - 1];
}
静态int应答(int[]A){

//这个例子是针对0的,我相信我有一个部分的解决方案,但对于我的一生,我不知道如何解释中间元素是罪犯的重复项(在线性时间内):
(1,X,1),(1,Y,1)
其中
X
Y
相等,但不是同一个元素。对于其他情况,首先向前迭代数组,记录每个值第一次出现的位置。如果元素不是其值的第一次出现,则从总数中减去
(arr\u length-curr\u index-1)
(跳过对最后两个元素的迭代)。如果违规元素是第一个元素,则所有这些都将是重复的。接下来,重复该过程,但向后迭代,以记录违规元素是三元组中最后一个元素的重复。现在我想到,元素可能会以这种方式计数两次,因此这是另一个需要解决的问题。第一个示例不也应该重复吗rn 4?您缺少
(1,1,2)
@Emil No。三元组的顺序应与数组中的顺序相同。对于任何三元组(a,b,c)
a
应位于
b
之前,而
b
c
之前,您如何知道这可以在O(n)时间内解决?