【问题标题】:Count Number of distinct subarrays计数不同子数组的数量
【发布时间】:2019-09-19 11:13:18
【问题描述】:

我最近在一次编码面试中遇到了这个问题。问题如下:

给定一个包含 n 个数字和一个数字 k 的数组 A[],计算不同子数组的总数,使得每个子数组最多包含 k 个奇数元素

1 <= n <= 1000
1 <= A[i] <= 250
1 <= k <= n

我使用了DP方法来解决问题,但是我的解决方案没有处理distinct部分。

public int distinctSubArraysWithAtmostKOddElements(int[] a, int k) {
        int l = a.length;
        int[][] dp = new int[k + 1][l];

        for (int j = 0; j < l; j++) {
            dp[0][j] = a[j] % 2 == 0 ? 1 : 0;
        }

        for (int i = 1; i <= k; i++) {
            dp[i][0] = 1;
        }

        for (int j = 1; j <= k; j++) {
            for (int i = 1; i < l; i++) {
                if (a[i] % 2 == 0) {
                    dp[j][i] = Math.max(dp[j - 1][i], 1 + Math.max(dp[j - 1][i - 1], dp[j][i - 1]));
                } else {
                    dp[j][i] = Math.max(dp[j - 1][i], 1 + dp[j - 1][i - 1]);
                }
            }
        }

        int tot = 0;
        for (int i = 0; i < l; i++) {
            tot += dp[k][i];
        }

        return tot;
    }

我的解决方案适用于 O(nk) 时间和空间。

我该如何处理这种独特性?有解决这个问题的数学公式吗?

编辑:

例如1:

A[] = {2,1,2,3} and k = 1
Distinct Subarrays are: {2}, {2,1}, {1}, {1,2}, {2,1,2}, {3}, {2,3}
So answer is 7.

例如 2:

A[] = {1,1,1} and k = 2
Distinct Subarrays are: {1}, {1,1}
So answer is 2.

例如 3:

A[] = {1,2,3} and k = 1
Distinct Subarrays are: {1}, {2}, {3}, {1,2}, {2,3}
So answer is 5.

【问题讨论】:

  • 每个子数组是否需要连续?比如数组[1,2,3,4],子数组[1,3,4]是否无效?
  • @Gilles-PhilippePaillé:yaa 子阵列必须是连续的。子数组的定义说它必须是连续的。另一方面,子序列不必是连续的。
  • 如果distinct 表示从不同索引开始的子数组的不同内容 - 问题看起来对面试来说是多余的。但也许这只是意味着“不同的开始/结束”索引?
  • @MBo: distinct 表示子数组的不同内容。我已经添加了示例。看看吧。
  • 如果没有不同的子数组,问题可以在 O(n) 时间内完成。

标签: arrays math dynamic-programming sub-array


【解决方案1】:

我们可以遍历所有子数组并存储有效子数组的哈希值。时间复杂度为O((n^2)*log(n)),内存复杂度为O(n^2)

int distinctSubArraysWithAtmostKOddElements(vector<int> a, int k)
{
        set<unsigned long long int> hashes;
        int prime = 163;
        for(int i = 0 ; i < a.size() ; i++)
        {
                int oddNow = 0;
                unsigned long long int hashNow = 0;

                for(int j = i ; j < a.size() ; j++)
                {
                        hashNow = hashNow * prime + a[j];
                        if( a[j] % 2) oddNow++;

                        if(oddNow <= k)
                                hashes.insert(hashNow);
                        else
                                break;
                }
        }

        return hashes.size();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2018-07-14
    相关资源
    最近更新 更多