The "Numbers With Same Consecutive Differences" problem asks you to find all positive integers of length n
such that the absolute difference between every two consecutive digits is exactly k
.
n
(the length of the number) and k
(the required absolute difference between every pair of consecutive digits).
For example, if n = 3
and k = 7
, valid numbers include 181 and 292 (since |1-8|=7, |8-1|=7).
To solve this problem, let's break down what is required:
n
where the difference between every two consecutive digits is exactly k
.n
-digit numbers and filtering them would be too slow, especially for large n
.
The brute-force approach would be to check all numbers from 10^{n-1}
to 10^n - 1
, but this is not efficient for large n
. Instead, we can build the numbers digit by digit, making sure that each new digit maintains the required consecutive difference.
This leads us to a recursive or breadth-first search (BFS) approach: for each possible starting digit (1-9), we add valid next digits (previous digit + k and previous digit - k, if they are between 0 and 9), and continue until we reach n
digits.
We can use either depth-first search (DFS) or BFS to build valid numbers:
n
digits.k = 0
, avoid adding the same digit twice.n
built in this way.This approach is efficient because it only explores valid combinations, avoiding unnecessary computation.
Let's walk through an example with n = 3
and k = 7
:
9 * 10^{n-1}
numbers to check, and each check takes O(n) time, so total time is O(n * 10^n).The "Numbers With Same Consecutive Differences" problem is elegantly solved by building numbers digit by digit, always maintaining the required consecutive difference. By using DFS or BFS, we avoid generating invalid numbers and greatly reduce computation compared to brute-force checking. The solution is efficient, leverages recursion or iterative construction, and highlights the power of combinatorial generation with constraints.
class Solution:
def numsSameConsecDiff(self, n: int, k: int) -> List[int]:
if n == 1:
return [i for i in range(10)]
res = []
def dfs(num, length):
if length == n:
res.append(num)
return
last_digit = num % 10
next_digits = set()
next_digits.add(last_digit + k)
next_digits.add(last_digit - k)
for next_digit in next_digits:
if 0 <= next_digit <= 9:
dfs(num * 10 + next_digit, length + 1)
for i in range(1, 10):
dfs(i, 1)
return res
class Solution {
public:
vector<int> numsSameConsecDiff(int n, int k) {
vector<int> res;
if (n == 1) {
for (int i = 0; i < 10; ++i) res.push_back(i);
return res;
}
function<void(int, int)> dfs = [&](int num, int length) {
if (length == n) {
res.push_back(num);
return;
}
int last_digit = num % 10;
set<int> next_digits = {last_digit + k, last_digit - k};
for (int next_digit : next_digits) {
if (0 <= next_digit && next_digit <= 9) {
dfs(num * 10 + next_digit, length + 1);
}
}
};
for (int i = 1; i < 10; ++i) {
dfs(i, 1);
}
return res;
}
};
class Solution {
public int[] numsSameConsecDiff(int n, int k) {
List<Integer> res = new ArrayList<>();
if (n == 1) {
for (int i = 0; i < 10; i++) res.add(i);
return res.stream().mapToInt(j -> j).toArray();
}
dfs(n, k, 0, 0, res);
int[] ans = new int[res.size()];
for (int i = 0; i < res.size(); i++) ans[i] = res.get(i);
return ans;
}
private void dfs(int n, int k, int num, int length, List<Integer> res) {
if (length == n) {
res.add(num);
return;
}
if (length == 0) {
for (int i = 1; i < 10; i++) {
dfs(n, k, i, 1, res);
}
} else {
int lastDigit = num % 10;
Set<Integer> nextDigits = new HashSet<>();
nextDigits.add(lastDigit + k);
nextDigits.add(lastDigit - k);
for (int next : nextDigits) {
if (next >= 0 && next <= 9) {
dfs(n, k, num * 10 + next, length + 1, res);
}
}
}
}
}
var numsSameConsecDiff = function(n, k) {
if (n === 1) return Array.from({length: 10}, (_, i) => i);
let res = [];
function dfs(num, length) {
if (length === n) {
res.push(num);
return;
}
let lastDigit = num % 10;
let nextDigits = new Set([lastDigit + k, lastDigit - k]);
for (let next of nextDigits) {
if (next >= 0 && next <= 9) {
dfs(num * 10 + next, length + 1);
}
}
}
for (let i = 1; i < 10; i++) {
dfs(i, 1);
}
return res;
};