Permutations
Order matters
All 3! = 6 orderings of three values.
This page covers two classic nested-loop patterns: listing all orderings of three numbers (permutations), and listing unordered pairs or triples (combinations). You will see distinct-index checks, the j = i + 1 trick, a live preview, worked Python examples, edge cases, and complexity.
Order matters
All 3! = 6 orderings of three values.
Order ignored
Unordered pairs with j > i.
No reuse
Do not reuse the same index in one line.
C(n,2)
Pair loops list each 2-subset once.
1, 2, 3
List all orderings for three integers.
Nested cost
Pairs are quadratic; triples are cubic.
Number combinations on this page means listing selections from a small list with nested loops. When order matters, you print permutations. When order does not matter, you print combinations.
Interviews love these patterns because they force you to talk about indices, duplicates, and asymptotic growth. Nested loops are enough for small sample sizes; larger inputs often use dedicated libraries later.
It is the clearest way to practice nested loops while learning the difference between order-sensitive and order-free listing.
Distinct i, j, k indices.
Use j = i + 1.
Use i < j < k.
3! = 6; C(4,2) = 6.
In short: nested loops pick indices; enforce distinct indices for permutations and increasing indices for combinations.
Given a small list of numbers, print either all orderings of three values or all unordered selections of size 2 (or 3).
# [1, 2, 3] -> 6 orderings (permutations)
# [10, 20, 30, 40] -> 6 unordered pairs | Item | Type | Description |
|---|---|---|
arr | list[int] | Source numbers to rearrange or pair. |
| Permutations | text lines | One line per ordering of three values. |
| Combinations | text lines | One line per unordered pair or triple. |
// Permutations of 3
for i in 0..2:
for j in 0..2:
for k in 0..2:
if i, j, k are all distinct:
print arr[i], arr[j], arr[k]
// Unordered pairs
for i in 0..n-2:
for j in i+1..n-1:
print arr[i], arr[j] | Pattern | Order? | Index rule |
|---|---|---|
| Permutations of 3 | Matters | i != j != k (all distinct) |
| Unordered pairs | Ignored | j = i + 1 .. n-1 |
| Unordered triples | Ignored | i < j < k |
| Goal | Pattern |
|---|---|
| Distinct indices | if i != j and j != k and i != k: |
| Unordered pairs | for j in range(i + 1, n): |
| Unordered triples | for k in range(j + 1, n): |
| Count perms of 3 | 3! = 6 |
| Count pairs | C(n, 2) = n*(n-1)/2 |
| Library later | itertools.permutations / combinations |
Same nested-loop toolbox — different index rules and interview signals.
distinct i,j,kOrder matters — 6 lines for [1,2,3]
j = i + 1Order ignored — no reverse duplicates
combinations(...)Production shortcut after you can explain loops
say order ruleState whether order matters up front
Reach for nested selection loops whenever you need every ordering or every unordered subset.
Practice indices and distinctness checks.
Clarify whether order changes the answer.
Try all pairs before smarter algorithms.
Connect output line count to n! and C(n,r).
Deep nested loops explode quickly.
Key benefit: one page that teaches both order-sensitive and order-free listing with the same nested-loop skill.
Enter three integers (e.g. 1, 2, 3) and list all orderings.
Three complete Python programs — permutations of three numbers, unordered pairs, and unordered triples. Click View Output to reveal sample console results.
Order matters: list every arrangement of three values.
Order matters here, so this is permutation listing.
def print_three_permutations(arr: list[int]) -> None:
print("All orderings (permutations) of the three numbers:")
for i in range(3):
for j in range(3):
for k in range(3):
if i != j and j != k and i != k:
print(arr[i], arr[j], arr[k])
def main() -> None:
arr = [1, 2, 3]
print_three_permutations(arr)
if __name__ == "__main__":
main() Each loop picks one position. The distinct-index guard ensures one slot is not reused in the same line. For three distinct values you always get 3! = 6 lines.
Increasing indices keep each unordered selection once.
Order does not matter in this pair listing, so we use j = i + 1.
def print_unordered_pairs(arr: list[int]) -> None:
n = len(arr)
print(f"All unordered pairs (choose 2 from {n}):")
for i in range(n):
for j in range(i + 1, n):
print(arr[i], arr[j])
def main() -> None:
arr = [10, 20, 30, 40]
print_unordered_pairs(arr)
if __name__ == "__main__":
main() Starting the inner loop at i + 1 skips reverse duplicates like (20, 10). That is choose 2 from 4, so you get C(4, 2) = 6 pairs.
Extend the pair idea to three nested loops with i < j < k.
def print_unordered_triples(arr: list[int]) -> None:
n = len(arr)
print(f"All unordered triples (choose 3 from {n}):")
for i in range(n):
for j in range(i + 1, n):
for k in range(j + 1, n):
print(arr[i], arr[j], arr[k])
def main() -> None:
arr = [10, 20, 30, 40]
print_unordered_triples(arr)
if __name__ == "__main__":
main() Each triple appears once because indices always increase. C(4, 3) = 4 lines — the natural extension of Example 2.
Put numbers in a list for index access.
Each loop picks one index / position.
Distinct indices, or strictly increasing indices.
One line per valid tuple or pair.
Trace how distinct indices produce the six permutations.
| i, j, k | Values | Printed? |
|---|---|---|
0,1,2 | 1 2 3 | Yes |
0,2,1 | 1 3 2 | Yes |
0,0,1 | — | No (i == j) |
1,0,2 | 2 1 3 | Yes |
… | remaining valid triples | Total 6 lines |
Invalid index triples are skipped; only distinct i, j, k print.
Where listing combinations and permutations shows up beyond the interview prompt.
Learn indices and guards clearly.
Example: three nested fors.
Try every unordered pair first.
Example: Example 2 style.
Verify line count equals n! or C(n,r).
Example: 6 perms, 6 pairs.
Show why (10,20) != (20,10) in perms.
Example: perm vs combo.
Permutation counts connect to n!.
Example: related topic.
Keep n small for hand-written loops.
Example: n ≈ 3–10.
Pro Tip: open with “Does order matter?” — that single question picks the right index rule.
Why nested-loop listing works well for small interview problems.
Dry-run indices on paper and see each line.
Same loops, two meaning of order.
Works with plain Python loops.
Pairs become triples by adding one loop.
Pro Tip: lead with loops in interviews; mention itertools only as a production aside.
Small habits that keep combination/permutation code interview-ready.
Decide permutation vs combination first.
For combinations, j = i + 1 beats filtering later.
Check against n! or C(n,r) before finishing.
Distinct indices ≠ unique printed value tuples.
Mention itertools for large production lists.
Pro Tip: if you see both (a,b) and (b,a), you probably wanted combinations, not permutations.
Mistakes that commonly break combination and permutation listings.
Printing arr[i] twice in one line.
→ Require all indices distinct for perms.
Printing both (10,20) and (20,10).
→ Start inner loop at i + 1.
Calling permutations “combinations”.
→ State whether order matters.
Expecting unique lines when input repeats.
→ Filter by value if needed.
Hand-writing O(n^k) for large n and k.
→ Use better algorithms or libraries.
Handle these before claiming the listing is complete.
Distinct indices can still print identical-looking triples.
For pair listing, if n < 2 there are no pairs to print.
Example 1 assumes exactly three elements.
Unordered triples print nothing.
Output volume grows fast — O(n²) / O(n³).
No selections — print a clear message if needed.
Handy follow-ups interviewers sometimes ask.
Try these variations to lock in the pattern.
Quick Takeaway: nest loops, then choose distinct indices (perms) or increasing indices (combos).
| Program | Time | Extra space |
|---|---|---|
| Triple nested loops (fixed size 3) | O(1) for fixed input | O(1) |
| Pairs from n elements | O(n²) | O(1) |
| Triples from n elements | O(n³) | O(1) |
Cost grows with how many selections you enumerate; output size is part of the story.
Number combinations on this page are nested-loop listings: distinct indices for permutations, increasing indices for combinations. Count expected lines with n! or C(n,r), watch duplicate values, and keep n small for hand-written loops.
Practice the three examples above, then continue to checking odd numbers.
Ask “does order matter?” then pick distinct indices or j = i + 1.
List selections with nested loops the interview-friendly way.
Order matters
Patternj = i + 1
RuleNo reused index
Guardn! / C(n,r)
CheckO(n²) pairs
AnalysisIn math, a combination ignores order, while a permutation treats different orders as different results. This page demonstrates both patterns using simple nested loops.
Learn how to check whether a number is odd in Python.
8 people found this page helpful