Talentd
FleetCode
Make and follow sheets.Sign in

Build Array Where You Can Find The Maximum Exactly K Comparisons solution and explanation

HardDynamic ProgrammingPrefix Sum7 min read65.3% acceptanceUpdated 9 Apr 2026
Build Array Where You Can Find The Maximum Exactly K Comparisons | DP Concepts 15 | Leetcode 1420codestorywithMIK · 32:13 · 23K viewsWatch on YouTube
9 more videos on this problem
  1. Build Array Where You Can Find The Maximum Exactly K Comparisons | DP Concepts 15 | Leetcode 1420codestorywithMIK · 32:13 · 23K views
  2. Leetcode Hard in 12 minutes | Build Array Where You Can Find The Maximum Exactly K Comparisons | DPCP Addict · 12:54 · 4K views
  3. Leetcode--1420 build array where you can find the maximum exactly k comparisons (DP)You Wu · 19:37 · 2K views
  4. Daily Leetcode #1285: Oct 07, 2023 - 1420. Build Array Where You Can Find The Maximum Exactly K..Programming Live with Larry · 16:24 · 1K views
  5. Build Array Where You Can Find The Maximum Exactly K Comparisons - JAVA - 1420 LeetCode Hard in 8minLeet Logics · 8:13 · 1K views
  6. Leetcode 1420. Build Array Where You Can Find The Maximum Exactly K ComparisonsFearless Learner · 18:26 · 942 views
  7. Build Array Where You Can Find the Maximum Exactly K Comparisons - LeetCode 1420 - PythonAlpha-Code · 21:37 · 734 views
  8. Build Array Where You Can Find The Maximum Exactly K Comparisons | Leetcode 1420 | DP | C++Tech Courses · 11:36 · 527 views
  9. 1420. Build Array Where You Can Find The Maximum Exactly K Comparisons | Leetcode daily challengeRuntime Error · 19:48 · 334 views
  10. LeetCode October Daily - D7 - 1420. Build Array Where You Can Find The Maximum Exactly K ComparisonsLeetCode The Hard Way · 26:26 · 269 views

The problem

You are given three integers n, m and k. Consider the following algorithm to find the maximum element of an array of positive integers:

You should build the array arr which has the following properties:

  • arr has exactly n integers.
  • 1 <= arr[i] <= m where (0 <= i < n).
  • After applying the mentioned algorithm to arr, the value search_cost is equal to k.

Return the number of ways to build the array arr under the mentioned conditions. As the answer may grow large, the answer must be computed modulo 109 + 7.

Example 1:

Input: n = 2, m = 3, k = 1
Output: 6
Explanation: The possible arrays are [1, 1], [2, 1], [2, 2], [3, 1], [3, 2] [3, 3]

Example 2:

Input: n = 5, m = 2, k = 3
Output: 0
Explanation: There are no possible arrays that satisfy the mentioned conditions.

Example 3:

Input: n = 9, m = 1, k = 1
Output: 1
Explanation: The only possible array is [1, 1, 1, 1, 1, 1, 1, 1, 1]

Constraints:

  • 1 <= n <= 50
  • 1 <= m <= 100
  • 0 <= k <= n

Approach overview

Problem Overview: You need to build an array of length n with values from 1 to m. While scanning the array from left to right, every time a new element becomes the maximum, the search cost increases by one. The task is to count how many arrays produce exactly k such maximum updates.

Approach 1: Recursion with Memoization (Top-Down DP) (Time: O(n * m * k), Space: O(n * m * k))

This approach models the problem as a recursive state. At position i, you track the current maximum value maxSoFar and how many comparisons (cost) have already been used. From this state, try placing every number from 1 to m. If the chosen value is greater than maxSoFar, the cost increases and the new maximum updates. Otherwise, the cost stays the same. Memoization stores results for the state (i, maxSoFar, cost) so repeated subproblems are avoided. This converts exponential recursion into polynomial dynamic programming. The state space has at most n * m * k combinations.

Approach 2: Dynamic Programming with 3D Table + Prefix Sum Optimization (Time: O(n * m * k), Space: O(n * m * k))

The bottom-up DP solution builds results iteratively. Define dp[i][j][c] as the number of arrays of length i where the maximum value is j and the search cost is c. Two transitions exist when extending the array:

1) Append a value ≤ j, which keeps the maximum unchanged. There are j choices, so multiply by j.

2) Append value j as a new maximum. This means the previous maximum was smaller, so sum all states with maximum < j and cost c-1.

The second transition would normally require iterating over all smaller maxima, but a running prefix sum speeds this up. Instead of scanning repeatedly, maintain cumulative sums across the j dimension. This reduces an extra loop and keeps the overall complexity at O(n * m * k). The method is deterministic, iterative, and typically faster in practice than recursion.

Both approaches rely on classic Dynamic Programming state modeling. The optimized transition uses cumulative sums similar to techniques in Prefix Sum problems. Thinking in terms of "current maximum" and "cost so far" is the key observation that unlocks the DP formulation.

Recommended for interviews: The 3D dynamic programming solution with prefix-sum optimization. Interviewers expect you to define the DP state (index, currentMax, cost) and derive the transitions clearly. Starting with a memoized recursive formulation shows strong problem decomposition skills, while converting it to an iterative DP demonstrates optimization awareness.

Approach 1: Dynamic Programming with 3D Table

We can use dynamic programming to solve this problem by maintaining a 3D array where dp[i][j][k] represents the number of ways to construct an array of length i, with values up to j and exactly k comparisons.

Recurrence relations can be defined by considering whether you want to extend the array by a value that does or doesn't increase the number of comparisons. Use modulo operations to manage large numbers.

MOD = 10**9 + 7

def numOfArrays(n, m, k):
    dp = [[[0]*(k+1) for _ in range(m+1)] for _ in range(n+1)]
    for j in range(1, m + 1):
        dp[1][j][1] = 1
    for i in range(2, n + 1):
        for j in range(1, m + 1):
            for z in range(1, k + 1):
                dp[i][j][z] = (dp[i-1][j][z] * j) % MOD
                for p in range(1, j):
                    dp[i][j][z] = (dp[i][j][z] + dp[i-1][p][z-1]) % MOD
    return sum(dp[n][j][k] for j in range(1, m+1)) % MOD
#include <vector>
using namespace std;

const int MOD = 1000000007;

int numOfArrays(int n, int m, int k) {
    vector<vector<vector<int>>> dp(n+1, vector<vector<int>>(m+1, vector<int>(k+1, 0)));
    for (int j = 1; j <= m; ++j) dp[1][j][1] = 1;
    for (int i = 2; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            for (int z = 1; z <= k; ++z) {
                dp[i][j][z] = ((long long)j * dp[i-1][j][z]) % MOD;
                for (int p = 1; p < j; ++p) {
                    dp[i][j][z] = (dp[i][j][z] + dp[i-1][p][z-1]) % MOD;
                }
            }
        }
    }
    int totalWays = 0;
    for (int j = 1; j <= m; ++j) {
        totalWays = (totalWays + dp[n][j][k]) % MOD;
    }
    return totalWays;
}

The initial step is to set the dp array for arrays of length 1 with exactly one comparison. It can also reach up to any value from 1 to m. As you build arrays, you either keep the maximum unchanged or increase it with a new maximum. The complexity arises from trying to keep a 3D table of results for all possible combinations of parameters and then aggregating those results.

Complexity

Time Complexity: O(n * m^2 * k). Space Complexity: O(n * m * k).

Try this approach in the editor

Approach 2: Recursion with Memoization

This approach uses recursion with memoization to avoid recomputing the solutions for subproblems. The recursive function attempts to build the array incrementally by deciding, step by step, which value to add, and whether it will increase the maximum so far. By caching previously computed results, it reduces repeated calculations.

import java.util.*;

public class Solution {
    private static final int MOD = 1000000007;
    private static int[][][] dp = new int[51][101][51];

    public int numOfArrays(int n, int m, int k) {
        for (int[][] arr2d : dp) for (int[] arr : arr2d) Arrays.fill(arr, -1);
        return numOfArraysHelper(n, m, k, 0, 0, 0);
    }

    private int numOfArraysHelper(int n, int m, int k, int index, int max, int cost) {
        if (index == n) return (cost == k) ? 1 : 0;
        if (cost > k) return 0;
        if (dp[index][max][cost] != -1) return dp[index][max][cost];

        int totalWays = 0;
        for (int i = 1; i <= m; ++i) {
            totalWays = (totalWays + numOfArraysHelper(n, m, k, index + 1, Math.max(max, i), cost + (i > max ? 1 : 0))) % MOD;
        }
        return dp[index][max][cost] = totalWays;
    }
}
const MOD = 10 ** 9 + 7;

function numOfArrays(n, m, k) {
  const dp = Array(n + 1).fill(0).map(() => Array(m + 1).fill(0).map(() => Array(k + 1).fill(-1)));

  const dfs = (i, max, z) => {
    if (i === n) return z === k ? 1 : 0;
    if (z > k) return 0;
    if (dp[i][max][z] !== -1) return dp[i][max][z];

    let ways = 0;
    for (let j = 1; j <= m; j++) {
      ways = (ways + dfs(i + 1, Math.max(max, j), z + (j > max ? 1 : 0))) % MOD;
    }
    return dp[i][max][z] = ways;
  };

  return dfs(0, 0, 0);
}

The Java solution initializes a 3D memoization table filled with -1 (uncomputed states) and recursively defines valid states for the dynamic structure of the array. It traverses through not only possible values to append but also considers whether adding the value modifies the comparison metric used (k comparisons).

Complexity

Time Complexity: O(n * m * k). Space Complexity: O(n * m * k) due to recursion stack and memoization storage.

Try this approach in the editor

Approach 3: Default Approach

func numOfArrays(n int, m int, k int) int {
	if k == 0 {
		return 0
	}
	mod := int(1e9) + 7
	dp := make([][][]int, n+1)
	for i := range dp {
		dp[i] = make([][]int, k+1)
		for j := range dp[i] {
			dp[i][j] = make([]int, m+1)
		}
	}
	for i := 1; i <= m; i++ {
		dp[1][1][i] = 1
	}
	for i := 2; i <= n; i++ {
		for c := 1; c <= k && c <= i; c++ {
			for j := 1; j <= m; j++ {
				dp[i][c][j] = (dp[i-1][c][j] * j) % mod
				for j0 := 1; j0 < j; j0++ {
					dp[i][c][j] = (dp[i][c][j] + dp[i-1][c-1][j0]) % mod
				}
			}
		}
	}
	ans := 0
	for i := 1; i <= m; i++ {
		ans = (ans + dp[n][k][i]) % mod
	}
	return ans
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Dynamic Programming with 3D Table

Time Complexity: O(n * m^2 * k). Space Complexity: O(n * m * k).

Recursion with Memoization

Time Complexity: O(n * m * k). Space Complexity: O(n * m * k) due to recursion stack and memoization storage.

Default Approach–

Complexity analysis

ApproachTimeSpaceWhen to Use
Recursion with MemoizationO(n * m * k)O(n * m * k)Good for understanding the state transition and building intuition before converting to iterative DP
3D Dynamic ProgrammingO(n * m * k * m)O(n * m * k)Straightforward implementation but slower due to iterating over smaller maxima
3D DP with Prefix Sum OptimizationO(n * m * k)O(n * m * k)Best practical solution when m is large; avoids repeated summation using prefix sums

Frequently asked questions

Is Build Array Where You Can Find The Maximum Exactly K Comparisons easy or hard?

LeetCode classifies this problem as Hard because it requires designing a three-dimensional dynamic programming state and optimizing transitions using prefix sums. Candidates must carefully reason about how the maximum value evolves while building the array and how the search cost changes.

Build Array Where You Can Find The Maximum Exactly K Comparisons Python/Java solution

Python and Java implementations typically follow the same DP formulation. Python solutions often use recursion with functools.lru_cache for memoization, while Java implementations commonly use iterative 3D arrays for bottom-up DP. Both approaches maintain states defined by index, current maximum, and search cost.

How to solve Build Array Where You Can Find The Maximum Exactly K Comparisons in O(n)?

Solving this problem strictly in O(n) is not feasible because the state depends on three parameters: array length n, value range m, and cost k. The optimal practical complexity is O(n * m * k) using dynamic programming with prefix sums. Each state transition is computed in constant time after prefix precomputation.

What is the best approach for Build Array Where You Can Find The Maximum Exactly K Comparisons?

The most efficient approach uses dynamic programming with a 3D state and prefix sum optimization. The state dp[i][j][c] represents arrays of length i where j is the current maximum and c is the search cost. Prefix sums allow fast computation of transitions where a new maximum is introduced. This reduces the complexity to O(n * m * k) time and O(n * m * k) space.

Is Build Array Where You Can Find The Maximum Exactly K Comparisons asked at Google/Amazon/Meta?

Dynamic programming problems involving state transitions and counting combinations appear frequently in interviews at companies like Google, Amazon, and Meta. Variants of this problem test the ability to define multi-dimensional DP states and optimize transitions using prefix sums or cumulative aggregates.

What data structure is used in Build Array Where You Can Find The Maximum Exactly K Comparisons?

The core data structure is a 3D dynamic programming table, typically implemented as a nested array or vector. Prefix sum arrays are used to accelerate transitions that sum values across ranges of maximums. Hash maps may also be used in memoized recursion to cache computed states.

What is the time complexity of Build Array Where You Can Find The Maximum Exactly K Comparisons?

The optimized dynamic programming solution runs in O(n * m * k) time with O(n * m * k) space. A naive DP version that iterates through all smaller maximum values adds an extra factor of m, leading to O(n * m^2 * k). Memoized recursion also achieves O(n * m * k) because each state is computed once.

Comments

Now write it yourselfClose this page and solve Build Array Where You Can Find The Maximum Exactly K Comparisons in the editor, without looking.
Practise Build Array Where You Can Find The Maximum Exactly K Comparisons