Talentd
FleetCode
Make and follow sheets.Sign in

Count the Number of Arrays with K Matching Adjacent Elements solution and explanation

HardCombinatoricsMath5 min read58.3% acceptanceUpdated 24 Mar 2026
Count the Number of Arrays with K Matching Adjacent Elements | Detailed Approach | Leetcode 3405codestorywithMIK · 33:16 · 8K viewsWatch on YouTube
9 more videos on this problem
  1. Count the Number of Arrays with K Matching Adjacent Elements | Detailed Approach | Leetcode 3405codestorywithMIK · 33:16 · 8K views
  2. 3405. Count the Number of Arrays with K Matching Adjacent Elements | Math | PnC | nCr | Mod InverseAryan Mittal · 19:56 · 6K views
  3. Count the Number of Arrays with K Matching Adjacent Elements | Leetcode 3405Techdose · 14:45 · 6K views
  4. 3405. Count the Number of Arrays with K Matching Adjacent Elements | Leetcode Daily - PythonLeetcode Daily · 6:34 · 1K views
  5. 3405. Count the Number of Arrays with K Matching Adjacent Elements - Day 17/30 Leetcode June ChallenProgramming Live with Larry · 20:52 · 1K views
  6. 3405. Count the Number of Arrays with K Matching Adjacent Elements - LeetCode [Hard] - 17 June 2025Intuit & Code · 24:32 · 1K views
  7. Leetcode 3405 | Count The Number Of Arrays With K Matching Adjacent Elements | Leetcode POTDCoding Grower · 34:34 · 587 views
  8. Leetcode 3405. Count the Number of Arrays with K Matching Adjacent ElementsElite Code · 37:40 · 523 views
  9. Leetcode 3405. Count the Number of Arrays with K Matching Adjacent Elements | Combinatorics + PythonStatLearn Tech · 13:40 · 435 views
  10. 3405. Count the Number of Arrays with K Matching Adjacent Elements (Leetcode Hard)Programming Live with Larry · 26:31 · 385 views

The problem

You are given three integers n, m, k. A good array arr of size n is defined as follows:

  • Each element in arr is in the inclusive range [1, m].
  • Exactly k indices i (where 1 <= i < n) satisfy the condition arr[i - 1] == arr[i].

Return the number of good arrays that can be formed.

Since the answer may be very large, return it modulo 109 + 7.

Example 1:

Input: n = 3, m = 2, k = 1

Output: 4

Explanation:

  • There are 4 good arrays. They are [1, 1, 2], [1, 2, 2], [2, 1, 1] and [2, 2, 1].
  • Hence, the answer is 4.

Example 2:

Input: n = 4, m = 2, k = 2

Output: 6

Explanation:

  • The good arrays are [1, 1, 1, 2], [1, 1, 2, 2], [1, 2, 2, 2], [2, 1, 1, 1], [2, 2, 1, 1] and [2, 2, 2, 1].
  • Hence, the answer is 6.

Example 3:

Input: n = 5, m = 2, k = 0

Output: 2

Explanation:

  • The good arrays are [1, 2, 1, 2, 1] and [2, 1, 2, 1, 2]. Hence, the answer is 2.

Constraints:

  • 1 <= n <= 105
  • 1 <= m <= 105
  • 0 <= k <= n - 1

Approach overview

Problem Overview: You need to count how many arrays of length n using values 1..m contain exactly k adjacent positions where a[i] == a[i+1]. The challenge is counting valid configurations without enumerating all m^n possibilities.

Approach 1: Dynamic Programming on Adjacent Matches (O(n * k) time, O(k) space)

A direct way is to build the array position by position while tracking how many matching adjacent pairs have been formed. Let dp[i][j] represent the number of ways to construct the first i elements with exactly j matching adjacent pairs. When adding element a[i], you have two choices: match the previous element (a[i] = a[i-1]) which increases the match count, or choose a different value (m-1 options) which does not. Transition through these two cases while ensuring the match count never exceeds k. This approach demonstrates the structure of the problem clearly but becomes less attractive when n is large.

Approach 2: Combinatorics + Fast Power (O(log n) time, O(1) space)

The optimal solution comes from observing that only the n-1 adjacent gaps determine whether a pair matches. Choose exactly k of these gaps where a[i] = a[i+1]. The number of ways to choose these positions is C(n-1, k). Once the matching gaps are fixed, the array effectively splits into n-k segments where the value must change between segments.

The first element has m choices. For every non-matching boundary (n-1-k of them), the next element must differ from the previous value, giving m-1 choices each time. The total number of valid arrays becomes:

C(n-1, k) * m * (m-1)^(n-1-k)

Because results are typically required modulo a large prime, compute the power using fast exponentiation. This reduces the exponentiation cost to O(log n). Combination values can be computed using factorials or an iterative formula depending on constraints.

This approach relies on counting configurations instead of constructing arrays. It converts the problem into pure combinatorics and modular arithmetic from math, which is why it scales easily even when n is very large.

Recommended for interviews: The combinatorics formula with fast exponentiation is the expected solution. Explaining the DP idea first shows you understand the state transitions, but recognizing the combinatorial structure and deriving C(n-1, k) * m * (m-1)^(n-1-k) demonstrates stronger problem-solving and mathematical insight.

Solution

For an array of length n, there are n - 1 pairs of adjacent elements. We need to select k of these n - 1 adjacent pairs such that the two elements in each of these k pairs are equal, and the remaining n - 1 - k adjacent pairs have different elements.

This is equivalent to splitting the array n - 1 - k times, resulting in n - k segments, where all elements in each segment are equal. The number of ways to split is C_{n - 1}^{n - 1 - k} = C_{n - 1}^{k}.

For the first segment, we can choose any element from [1, m]. For the remaining n - k - 1 segments, we just need to ensure that the element in each segment is different from the previous segment, so each of these segments has m - 1 choices. In total, there are m times (m - 1)^{n - k - 1} ways to choose.

Combining the two parts above, we get the answer:

$ C_{n - 1}^{k} times m times (m - 1)^{n - k - 1} bmod (10^9 + 7)

In the code implementation, we can precompute factorials and inverses, and use fast power to calculate combinations.

Ignoring the preprocessing time and space, the time complexity is O(log (n - k)), and the space complexity is O(1)$.

mx = 10**5 + 10
mod = 10**9 + 7
f = [1] + [0] * mx
g = [1] + [0] * mx

for i in range(1, mx):
    f[i] = f[i - 1] * i % mod
    g[i] = pow(f[i], mod - 2, mod)


def comb(m: int, n: int) -> int:
    return f[m] * g[n] * g[m - n] % mod


class Solution:
    def countGoodArrays(self, n: int, m: int, k: int) -> int:
        return comb(n - 1, k) * m * pow(m - 1, n - k - 1, mod) % mod
class Solution {
    private static final int N = (int) 1e5 + 10;
    private static final int MOD = (int) 1e9 + 7;
    private static final long[] f = new long[N];
    private static final long[] g = new long[N];

    static {
        f[0] = 1;
        g[0] = 1;
        for (int i = 1; i < N; ++i) {
            f[i] = f[i - 1] * i % MOD;
            g[i] = qpow(f[i], MOD - 2);
        }
    }

    public static long qpow(long a, int k) {
        long res = 1;
        while (k != 0) {
            if ((k & 1) == 1) {
                res = res * a % MOD;
            }
            k >>= 1;
            a = a * a % MOD;
        }
        return res;
    }

    public static long comb(int m, int n) {
        return (int) f[m] * g[n] % MOD * g[m - n] % MOD;
    }

    public int countGoodArrays(int n, int m, int k) {
        return (int) (comb(n - 1, k) * m % MOD * qpow(m - 1, n - k - 1) % MOD);
    }
}
const int MX = 1e5 + 10;
const int MOD = 1e9 + 7;
long long f[MX];
long long g[MX];

long long qpow(long a, int k) {
    long res = 1;
    while (k != 0) {
        if ((k & 1) == 1) {
            res = res * a % MOD;
        }
        k >>= 1;
        a = a * a % MOD;
    }
    return res;
}

int init = []() {
    f[0] = g[0] = 1;
    for (int i = 1; i < MX; ++i) {
        f[i] = f[i - 1] * i % MOD;
        g[i] = qpow(f[i], MOD - 2);
    }
    return 0;
}();

long long comb(int m, int n) {
    return f[m] * g[n] % MOD * g[m - n] % MOD;
}

class Solution {
public:
    int countGoodArrays(int n, int m, int k) {
        return comb(n - 1, k) * m % MOD * qpow(m - 1, n - k - 1) % MOD;
    }
};
const MX = 1e5 + 10;
const MOD = BigInt(1e9 + 7);

const f: bigint[] = Array(MX).fill(1n);
const g: bigint[] = Array(MX).fill(1n);

function qpow(a: bigint, k: number): bigint {
    let res = 1n;
    while (k !== 0) {
        if ((k & 1) === 1) {
            res = (res * a) % MOD;
        }
        a = (a * a) % MOD;
        k >>= 1;
    }
    return res;
}

(function init() {
    for (let i = 1; i < MX; ++i) {
        f[i] = (f[i - 1] * BigInt(i)) % MOD;
        g[i] = qpow(f[i], Number(MOD - 2n));
    }
})();

function comb(m: number, n: number): bigint {
    return (((f[m] * g[n]) % MOD) * g[m - n]) % MOD;
}

export function countGoodArrays(n: number, m: number, k: number): number {
    const ans = (((comb(n - 1, k) * BigInt(m)) % MOD) * qpow(BigInt(m - 1), n - k - 1)) % MOD;
    return Number(ans);
}
const MX = 1e5 + 10
const MOD = 1e9 + 7

var f [MX]int64
var g [MX]int64

func qpow(a int64, k int) int64 {
	res := int64(1)
	for k != 0 {
		if k&1 == 1 {
			res = res * a % MOD
		}
		a = a * a % MOD
		k >>= 1
	}
	return res
}

func init() {
	f[0], g[0] = 1, 1
	for i := 1; i < MX; i++ {
		f[i] = f[i-1] * int64(i) % MOD
		g[i] = qpow(f[i], MOD-2)
	}
}

func comb(m, n int) int64 {
	return f[m] * g[n] % MOD * g[m-n] % MOD
}

func countGoodArrays(n int, m int, k int) int {
	ans := comb(n-1, k) * int64(m) % MOD * qpow(int64(m-1), n-k-1) % MOD
	return int(ans)
}
impl Solution {
    pub fn count_good_arrays(n: i32, m: i32, k: i32) -> i32 {
        const N: usize = 1e5 as usize + 10;
        const MOD: i64 = 1_000_000_007;
        use std::sync::OnceLock;

        static F: OnceLock<Vec<i64>> = OnceLock::new();
        static G: OnceLock<Vec<i64>> = OnceLock::new();

        fn qpow(mut a: i64, mut k: i64, m: i64) -> i64 {
            let mut res = 1;
            while k != 0 {
                if k & 1 == 1 {
                    res = res * a % m;
                }
                a = a * a % m;
                k >>= 1;
            }
            res
        }

        fn init() -> (&'static Vec<i64>, &'static Vec<i64>) {
            F.get_or_init(|| {
                let mut f = vec![1i64; N];
                for i in 1..N {
                    f[i] = f[i - 1] * i as i64 % MOD;
                }
                f
            });

            G.get_or_init(|| {
                let f = F.get().unwrap();
                let mut g = vec![1i64; N];
                for i in 1..N {
                    g[i] = qpow(f[i], MOD - 2, MOD);
                }
                g
            });

            (F.get().unwrap(), G.get().unwrap())
        }

        fn comb(f: &[i64], g: &[i64], m: usize, n: usize) -> i64 {
            f[m] * g[n] % MOD * g[m - n] % MOD
        }

        let (f, g) = init();
        let n = n as usize;
        let m = m as i64;
        let k = k as usize;

        let c = comb(f, g, n - 1, k);
        let pow = qpow(m - 1, (n - 1 - k) as i64, MOD);
        (c * m % MOD * pow % MOD) as i32
    }
}
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
Dynamic Programming on Adjacent MatchesO(n * k)O(k)Useful for understanding transitions and when constraints are small
Combinatorics + Fast PowerO(log n)O(1)Optimal solution for large n; converts the problem to counting choices of matching gaps

Frequently asked questions

Is Count the Number of Arrays with K Matching Adjacent Elements easy or hard?

The problem is rated Hard because the key insight is combinatorial. A brute force or straightforward DP approach is easy to derive, but recognizing that the n-1 gaps determine the number of matches and converting the problem into C(n-1, k) * m * (m-1)^(n-1-k) requires deeper mathematical reasoning.

Count the Number of Arrays with K Matching Adjacent Elements Python/Java solution

Implement the formula C(n-1, k) * m * (m-1)^(n-1-k) under modulo arithmetic. Use fast exponentiation to compute powers efficiently and either precompute factorials for combinations or calculate combinations iteratively. The same logic works in Python, Java, C++, Go, TypeScript, and Rust.

How to solve Count the Number of Arrays with K Matching Adjacent Elements in O(log n)?

Treat each adjacent pair as a gap that either matches or differs. Choose k of the n-1 gaps to be equal using combinations. The array then has m choices for the first element and m-1 choices for each of the n-1-k non-matching gaps. Compute the result as C(n-1, k) * m * (m-1)^(n-1-k) with fast exponentiation.

What is the best approach for Count the Number of Arrays with K Matching Adjacent Elements?

The most efficient method uses combinatorics. Choose k matching adjacent positions among the n-1 gaps using C(n-1, k). The first element has m choices, and every non-matching boundary has m-1 choices, producing the formula C(n-1, k) * m * (m-1)^(n-1-k). Fast exponentiation computes the power term in O(log n) time.

Is Count the Number of Arrays with K Matching Adjacent Elements asked at Google/Amazon/Meta?

This type of combinatorics counting problem appears in interviews at companies like Google, Amazon, and Meta, especially for roles that emphasize mathematical reasoning or competitive programming style questions. Variants involving adjacent constraints and combinatorial counting are common.

What data structure is used in Count the Number of Arrays with K Matching Adjacent Elements?

The optimal solution does not rely on complex data structures. It primarily uses mathematical computation: combinations, modular arithmetic, and fast exponentiation. A dynamic programming version may use an array to store dp states for match counts.

What is the time complexity of Count the Number of Arrays with K Matching Adjacent Elements?

The optimal combinatorics solution runs in O(log n) time due to fast modular exponentiation. Space complexity is O(1) aside from constant arithmetic variables. A dynamic programming alternative takes O(n * k) time and O(k) space.

Comments

Now write it yourselfClose this page and solve Count the Number of Arrays with K Matching Adjacent Elements in the editor, without looking.
Practise Count the Number of Arrays with K Matching Adjacent Elements