2

I recently came across this question in one of the coding interviews. The question is as follows:

Given an array A[] of n numbers and a number k, count the total number of distinct subarrays such that each subarray contains at most k odd elements.

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

I used a DP approach to solve the problem, but my solution does not take care of the distinct part.

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

My solution works in O(nk) time and space.

How can I take care of the distinctness ? Is there a mathematical formula that solves this problem?

Edit:

Eg 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.

Eg 2:

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

Eg 3:

A[] = {1,2,3} and k = 1
Distinct Subarrays are: {1}, {2}, {3}, {1,2}, {2,3}
So answer is 5.
User_Targaryen
  • 4,125
  • 4
  • 30
  • 51
  • Does each sub-array needs to be contiguous? For example, for an array `[1,2,3,4]`, is the sub-array `[1,3,4]` invalid? – Gilles-Philippe Paillé Apr 30 '19 at 19:51
  • @Gilles-PhilippePaillé: yaa subarrays have to be contiguous. The very definition of subarray says that it has to be contiguous. Subsequences on the other hand need not be contiguous. – User_Targaryen May 01 '19 at 02:31
  • 1
    If `distinct` means distinct contents for subarrays starting from different indexes - problem looks overkill for interview. But perhaps this just means "different start/end" indexes? – MBo May 01 '19 at 05:13
  • @MBo: `distinct` means distinct contents of subarrays. I have added examples. Have a look. – User_Targaryen May 01 '19 at 11:52
  • Without distinct subarrays, the problem can be done in O(n) time. – Mukul Gupta May 01 '19 at 20:21

1 Answers1

1

We can iterate over all subarrays and store the hashes of the valid subarrays.The time complexity is O((n^2)*log(n)) and memory complexity 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();
}