Array combinations
Permutations
Array algorithms
Combinatorics
Data structures

All possible combinations of an array

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When people ask for "all possible combinations of an array," they usually mean one of two things: all subsets of the array, or all groups of a fixed size. Those are different from permutations, where order matters.

Getting that distinction right matters because the algorithm, output size, and performance all change. Before writing code, decide whether you want the full power set, combinations of length k, or ordered arrangements.

Combination vs Permutation

For an array ["A", "B", "C"], the combinations of size 2 are:

text
["A", "B"]
["A", "C"]
["B", "C"]

The permutations of size 2 are:

text
1["A", "B"]
2["B", "A"]
3["A", "C"]
4["C", "A"]
5["B", "C"]
6["C", "B"]

If you want every possible combination across all lengths, you are asking for the power set. An array of length n has 2^n subsets, including the empty one.

Backtracking for Fixed-Size Combinations

Backtracking is the standard way to generate combinations of size k. The idea is simple: choose the current element or skip it, while keeping the result in sorted index order so duplicates from reordering never appear.

python
1def combinations(nums, k):
2    result = []
3    current = []
4
5    def backtrack(start):
6        if len(current) == k:
7            result.append(current.copy())
8            return
9
10        for i in range(start, len(nums)):
11            current.append(nums[i])
12            backtrack(i + 1)
13            current.pop()
14
15    backtrack(0)
16    return result
17
18
19print(combinations([1, 2, 3, 4], 2))

Output:

text
[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

This algorithm visits exactly the valid combinations. For fixed k, that is usually what you want.

Generating the Full Power Set

If you need combinations of every possible size, generate the power set instead. One clean approach is iterative: start with the empty subset, then extend existing subsets with each new element.

python
1def power_set(nums):
2    subsets = [[]]
3
4    for num in nums:
5        new_subsets = [subset + [num] for subset in subsets]
6        subsets.extend(new_subsets)
7
8    return subsets
9
10
11print(power_set([1, 2, 3]))

Output:

text
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

This is concise and easy to reason about. The unavoidable cost is O(2^n) because there are 2^n subsets to return.

Using the Standard Library

If you are using Python, itertools.combinations is the best default for fixed-size combinations. It is fast, memory-efficient, and already handles the index ordering correctly.

python
1from itertools import combinations
2
3items = ["red", "green", "blue", "black"]
4
5for group in combinations(items, 3):
6    print(group)

For all sizes, combine it with a loop:

python
1from itertools import combinations
2
3def all_combinations(items):
4    for size in range(len(items) + 1):
5        yield from combinations(items, size)
6
7
8for combo in all_combinations([1, 2, 3]):
9    print(combo)

This version yields results lazily instead of building one huge list up front.

Handling Duplicate Values

Arrays sometimes contain repeated values such as [1, 1, 2]. If you generate combinations by index, you can end up with repeated value combinations that look identical in the output.

To avoid that, sort the input and skip repeated choices at the same recursion depth:

python
1def unique_combinations(nums, k):
2    nums.sort()
3    result = []
4    current = []
5
6    def backtrack(start):
7        if len(current) == k:
8            result.append(current.copy())
9            return
10
11        for i in range(start, len(nums)):
12            if i > start and nums[i] == nums[i - 1]:
13                continue
14            current.append(nums[i])
15            backtrack(i + 1)
16            current.pop()
17
18    backtrack(0)
19    return result

That pattern is common in interview problems and search code.

Common Pitfalls

The biggest mistake is mixing up combinations and permutations. If order does not matter, do not use an algorithm that rearranges the same elements into multiple orders.

Another common issue is forgetting the output size. Returning all subsets is exponential. That is not an implementation bug; it is inherent in the problem. If n is large, prefer a generator and process results incrementally.

Duplicates are another trap. If the input can contain repeated values, define whether combinations are based on positions or values. Those produce different answers.

Finally, do not mutate and store the same working list object without copying it. If you append current directly during backtracking, later modifications will corrupt every stored result.

Summary

  • "All combinations" can mean fixed-size combinations or the full power set.
  • Combinations ignore order; permutations do not.
  • Backtracking is a clear approach for combinations of size k.
  • The power set has 2^n subsets, so the output size grows very quickly.
  • In Python, itertools.combinations is usually the best fixed-size solution.
  • If the input contains duplicates, sort first and skip repeated choices carefully.

Course illustration
Course illustration

All Rights Reserved.