Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
You are given an array of positive integers nums, and a positive integer k.
You are allowed to perform an operation once on nums, where in each operation you can remove any non-overlapping prefix and suffix from nums such that nums remains non-empty.
You need to find the x-value of nums, which is the number of ways to perform this operation so that the product of the remaining elements leaves a remainder of x when divided by k.
Return an array result of size k where result[x] is the x-value of nums for 0 <= x <= k - 1.
A prefix of an array is a subarray that starts from the beginning of the array and extends to any point within it.
A suffix of an array is a subarray that starts at any point within the array and extends to the end of the array.
Note that the prefix and suffix to be chosen for the operation can be empty.
Example 1:
Input: nums = [1,2,3,4,5], k = 3
Output: [9,2,4]
Explanation:
x = 0, the possible operations include all possible ways to remove non-overlapping prefix/suffix that do not remove nums[2] == 3.x = 1, the possible operations are:
[2, 3, 4, 5]. nums becomes [1].[1, 2, 3] and the suffix [5]. nums becomes [4].x = 2, the possible operations are:
[3, 4, 5]. nums becomes [1, 2].[1] and the suffix [3, 4, 5]. nums becomes [2].[1, 2, 3] and the empty suffix. nums becomes [4, 5].[1, 2, 3, 4] and the empty suffix. nums becomes [5].Example 2:
Input: nums = [1,2,4,8,16,32], k = 4
Output: [18,1,2,0]
Explanation:
x = 0, the only operations that do not result in x = 0 are:
[4, 8, 16, 32]. nums becomes [1, 2].[2, 4, 8, 16, 32]. nums becomes [1].[1] and the suffix [4, 8, 16, 32]. nums becomes [2].x = 1, the only possible operation is:
[2, 4, 8, 16, 32]. nums becomes [1].x = 2, the possible operations are:
[4, 8, 16, 32]. nums becomes [1, 2].[1] and the suffix [4, 8, 16, 32]. nums becomes [2].x = 3, there is no possible way to perform the operation.Example 3:
Input: nums = [1,1,2,1,1], k = 2
Output: [9,6]
Constraints:
1 <= nums[i] <= 1091 <= nums.length <= 1051 <= k <= 5Problem summary: You are given an array of positive integers nums, and a positive integer k. You are allowed to perform an operation once on nums, where in each operation you can remove any non-overlapping prefix and suffix from nums such that nums remains non-empty. You need to find the x-value of nums, which is the number of ways to perform this operation so that the product of the remaining elements leaves a remainder of x when divided by k. Return an array result of size k where result[x] is the x-value of nums for 0 <= x <= k - 1. A prefix of an array is a subarray that starts from the beginning of the array and extends to any point within it. A suffix of an array is a subarray that starts at any point within the array and extends to the end of the array. Note that the prefix and suffix to be chosen for the operation can be empty.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Math · Dynamic Programming
[1,2,3,4,5] 3
[1,2,4,8,16,32] 4
[1,1,2,1,1] 2
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3524: Find X Value of Array I
class Solution {
public long[] resultArray(int[] nums, int k) {
long[] ans = new long[k];
// dp[r] := the number of subarrays ending at current position with
// product % k == r
long[] dp = new long[k];
for (final int num : nums) {
long[] newDp = new long[k];
final int numMod = num % k;
// Start new subarray with only `num`.
newDp[numMod] = 1;
// Extend all previous subarrays.
for (int i = 0; i < k; ++i) {
final int newMod = (int) (1L * i * numMod % k);
newDp[newMod] += dp[i];
}
// Accumulate counts into ans.
for (int i = 0; i < k; ++i)
ans[i] += newDp[i];
dp = newDp;
}
return ans;
}
}
// Accepted solution for LeetCode #3524: Find X Value of Array I
package main
// https://space.bilibili.com/206214
func resultArray(nums []int, k int) []int64 {
ans := make([]int64, k)
f := make([]int, k)
for _, v := range nums {
nf := make([]int, k)
nf[v%k] = 1
for y, c := range f {
nf[y*v%k] += c
}
f = nf
for x, c := range f {
ans[x] += int64(c)
}
}
return ans
}
func resultArray1(nums []int, k int) []int64 {
ans := make([]int64, k)
f := make([][]int, len(nums)+1)
for i := range f {
f[i] = make([]int, k)
}
for i, v := range nums {
f[i+1][v%k] = 1
for y, c := range f[i] {
f[i+1][y*v%k] += c
}
for x, c := range f[i+1] {
ans[x] += int64(c)
}
}
return ans
}
# Accepted solution for LeetCode #3524: Find X Value of Array I
class Solution:
def resultArray(self, nums: list[int], k: int) -> list[int]:
ans = [0] * k
# dp[r] := the number of subarrays ending at current position with
# product % k == r
dp = [0] * k
for num in nums:
newDp = [0] * k
numMod = num % k
# Start new subarray with only `num`
newDp[numMod] = 1
# Extend all previous subarrays
for i in range(k):
newMod = (i * numMod) % k
newDp[newMod] += dp[i]
# Accumulate counts into ans
for i in range(k):
ans[i] += newDp[i]
dp = newDp
return ans
// Accepted solution for LeetCode #3524: Find X Value of Array I
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #3524: Find X Value of Array I
// class Solution {
// public long[] resultArray(int[] nums, int k) {
// long[] ans = new long[k];
// // dp[r] := the number of subarrays ending at current position with
// // product % k == r
// long[] dp = new long[k];
//
// for (final int num : nums) {
// long[] newDp = new long[k];
// final int numMod = num % k;
// // Start new subarray with only `num`.
// newDp[numMod] = 1;
// // Extend all previous subarrays.
// for (int i = 0; i < k; ++i) {
// final int newMod = (int) (1L * i * numMod % k);
// newDp[newMod] += dp[i];
// }
// // Accumulate counts into ans.
// for (int i = 0; i < k; ++i)
// ans[i] += newDp[i];
// dp = newDp;
// }
//
// return ans;
// }
// }
// Accepted solution for LeetCode #3524: Find X Value of Array I
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #3524: Find X Value of Array I
// class Solution {
// public long[] resultArray(int[] nums, int k) {
// long[] ans = new long[k];
// // dp[r] := the number of subarrays ending at current position with
// // product % k == r
// long[] dp = new long[k];
//
// for (final int num : nums) {
// long[] newDp = new long[k];
// final int numMod = num % k;
// // Start new subarray with only `num`.
// newDp[numMod] = 1;
// // Extend all previous subarrays.
// for (int i = 0; i < k; ++i) {
// final int newMod = (int) (1L * i * numMod % k);
// newDp[newMod] += dp[i];
// }
// // Accumulate counts into ans.
// for (int i = 0; i < k; ++i)
// ans[i] += newDp[i];
// dp = newDp;
// }
//
// return ans;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Pure recursion explores every possible choice at each step. With two choices per state (take or skip), the decision tree has 2ⁿ leaves. The recursion stack uses O(n) space. Many subproblems are recomputed exponentially many times.
Each cell in the DP table is computed exactly once from previously solved subproblems. The table dimensions determine both time and space. Look for the state variables — each unique combination of state values is one cell. Often a rolling array can reduce space by one dimension.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.
Wrong move: An incomplete state merges distinct subproblems and caches incorrect answers.
Usually fails on: Correctness breaks on cases that differ only in hidden state.
Fix: Define state so each unique subproblem maps to one DP cell.