Ordered ways to reach a total
Given distinct positive integers nums and a target, return the number of ordered
sequences of elements of nums (each usable any number of times) that add up to target. Sequences
with the same numbers in a different order count separately. The empty sequence makes 0.
Examples
| Input | Output | Why |
|---|---|---|
nums = [1,2,3], target = 4 | 7 | 1111, 112, 121, 211, 22, 13, 31. |
nums = [9], target = 3 | 0 | Nothing fits. |
nums = [1,2], target = 5 | 8 | The Fibonacci staircase. |
Constraints
- 1 ≤ nums.length ≤ 200
- 1 ≤ nums[i] ≤ 1000
- 0 ≤ target ≤ 1000
- The answer fits in a 64-bit integer
Hints
Hint 1
Let ways[t] be the number of ordered sequences summing to t; ways[0] = 1.
Hint 2
The last element of a sequence summing to t is some x: ways[t] = Σ ways[t − x].
Hint 3
Totals on the outer loop, numbers inside: that is what makes order count.
Where people lose marks
- Coins-outside loop order, which counts combinations instead.
- ways[0] = 0.
Dry run on [1,2,3],4
Read it one frame at a time, the way you would trace the code on paper in an interview. Each frame shows the state after the step it describes.
-
Step 1 / 5ways10
One way to make 0: the empty sequence.
-
Step 2 / 5ways1011
ways[1] = ways[0] = 1.
-
Step 3 / 5ways101122
ways[2] = ways[1] + ways[0] = 2.
-
Step 4 / 5ways10112243
ways[3] = ways[2] + ways[1] + ways[0] = 4.
-
Step 5 / 5ways1011224374
ways[4] = ways[3] + ways[2] + ways[1] = 7.
How to think about it
Classify sequences summing to t by their last element x: the rest is any ordered sequence summing to t − x. So
ways[t] = Σ over x of ways[t − x], filled for t upwards with ways[0] = 1. Because each total
considers every possible last element, 1 + 2 and 2 + 1 are built from different last elements and both counted: the
opposite of coin change, where coins on the outside count each combination once.
Complexity. Time O(target · n) · Space O(target)
The solution, in six languages
Each one is compiled and run against the test table before it is published. Java is reviewed by hand.
def ordered_ways(nums, target):
ways = [1] + [0] * target # ways[t]: ordered sequences summing to t
for t in range(1, target + 1): # totals outside: order matters
for x in nums:
if x <= t:
ways[t] += ways[t - x] # x is the last element
return ways[target]#include <vector>
long long solve(const std::vector<int>& nums, int target) {
std::vector<long long> ways(target + 1, 0);
ways[0] = 1;
for (int t = 1; t <= target; ++t) // totals outside: order matters
for (int x : nums)
if (x <= t) ways[t] += ways[t - x];
return ways[target];
}class Solution {
public long orderedWays(int[] nums, int target) {
long[] ways = new long[target + 1];
ways[0] = 1;
for (int t = 1; t <= target; t++) // totals outside: order matters
for (int x : nums) if (x <= t) ways[t] += ways[t - x];
return ways[target];
}
}function orderedWays(nums, target) {
const ways = [1, ...new Array(target).fill(0)];
for (let t = 1; t <= target; t++) // totals outside: order matters
for (const x of nums) if (x <= t) ways[t] += ways[t - x];
return ways[target];
}fn solve(nums: &[i64], target: i64) -> i64 {
let n = target as usize;
let mut ways = vec![0i64; n + 1];
ways[0] = 1;
for t in 1..=n { // totals outside: order matters
for &x in nums {
let x = x as usize;
if x <= t {
ways[t] += ways[t - x];
}
}
}
ways[n]
}import Data.Array
solve :: [Int] -> Int -> Int
solve nums target = ways ! target
where
-- ways ! t: ordered sequences summing to t, classified by their last element
ways = listArray (0, target) (1 : [sum [ways ! (t - x) | x <- nums, x <= t] | t <- [1 .. target]]) :: Array Int Int
Variants to try
- Negative numbers allowed: the count can be infinite unless sequence length is bounded.
- At most k elements: add the length to the state.
- Answer modulo 10⁹ + 7 for large targets.
Next problems
Dice rolls with a target sum
Roll n dice with k faces each. In how many ways can the faces add up to the target? Exactly n picks, so the number of dice used is part of the state.
Open the problem → Medium15 minSubsets with a given sum
Count the subsets of a list (by position) that add up to the target. The 0/1 knapsack with sum: totals downwards, each element at most once.
Open the problem → Easy10 minThe cheapest way up a staircase
Each step has a cost; climb one or two steps at a time; start on step 0 or 1. Return the cheapest way past the top.
Open the problem →Write a solution and run it against the real test table.
Keep going
Dice rolls with a target sum
Roll n dice with k faces each. In how many ways can the faces add up to the target? Exactly n picks, so the number of dice used is part of the state.
Open the problem → Medium15 minSubsets with a given sum
Count the subsets of a list (by position) that add up to the target. The 0/1 knapsack with sum: totals downwards, each element at most once.
Open the problem → Easy10 minThe cheapest way up a staircase
Each step has a cost; climb one or two steps at a time; start on step 0 or 1. Return the cheapest way past the top.
Open the problem → Dynamic programmingThe pattern behind it
Write the recursion, notice the repeats, fill a table in an order that makes each entry final.
Read the pattern →Preparing for a real process? Quant interview preparation, or book a free 20-minute call.