967. Numbers With Same Consecutive Differences
Numbers With Same Consecutive Differences
Given two integers n and k, return an array of all the integers of length n
where the difference between every two consecutive digits is k
. You may return the answer in any order.
Note that the integers should not have leading zeros. Integers as 02
and 043
are not allowed.
Example 1:
Input: n = 3, k = 7 Output: [181,292,707,818,929] Explanation: Note that 070 is not a valid number, because it has leading zeroes.
Example 2:
Input: n = 2, k = 1
Output: [10,12,21,23,32,34,43,45,54,56,65,67,76,78,87,89,98]
Constraints:
2 <= n <= 9
0 <= k <= 9
Approach) Brute Force
/**
* @param {number} n
* @param {number} k
* @return {number[]}
*/
var numsSameConsecDiff = function (n, k) {
let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let len = 1; len < n; len++) {
const newNums = [];
for (const num of nums) {
const remainder = num % 10;
const incNum = remainder + k;
if (incNum >= 0 && incNum <= 9) {
newNums.push(num * 10 + incNum);
}
const decNum = remainder - k;
if (decNum >= 0 && decNum <= 9 && incNum !== decNum) {
newNums.push(num * 10 + decNum);
}
}
nums = newNums;
}
return nums;
};
Approach) Dynamic Programming
/**
* @param {number} n
* @param {number} k
* @return {number[]}
*/
var numsSameConsecDiff = function(n, k) {
let list = [1, 2, 3, 4, 5, 6, 7, 8, 9]; // integers list
while(--n > 0){
let tmp = [];
for(let val of list){
let rem = val % 10;
if(rem + k < 10){ // map digit by digit
tmp.push(val * 10 + rem + k);
}
if(k != 0 && rem - k >= 0) { // map digit by digit
tmp.push(val * 10 + rem - k)
}
}
list = tmp;
}
return list
};
var numsSameConsecDiff = function(N, K) {
let prevSet = new Set([0,1,2,3,4,5,6,7,8,9]);
for (let n = 2; n <= N; n++) { // we start at 2 since n = 1 is just the one digit numbers 0 through 9
const newSet = new Set();
for (const prevVal of prevSet) {
const lastDig = prevVal % 10;
const plusK = lastDig + K;
const minusK = lastDig - K;
if (prevVal > 0 && plusK < 10) newSet.add((prevVal * 10) + plusK);
if (prevVal > 0 && minusK >= 0) newSet.add((prevVal * 10) + minusK);
}
prevSet = newSet;
}
return [...prevSet];
};
Approach) Recursion
var numsSameConsecDiff = function (N, K) {
let ret = new Set();
let numsSameConsecDiffRec = (tmp) => {
if (tmp.length == N) {
let skip = tmp.length > 1 && tmp[0] == '0';
if (!skip) ret.add(Number(tmp.join("")));
return;
}
let last = tmp[tmp.length - 1];
if (last - K >= 0) numsSameConsecDiffRec([...tmp, last - K]);
if (last + K <= 9) numsSameConsecDiffRec([...tmp, last + K]);
}
for (let i = 0; i <= 9; i++) numsSameConsecDiffRec([i]);
return [...ret];
};
Approach) Depth First Search
const numsSameConsecDiff = (N, K, ans = []) => {
if (N === 1) return [0,1,2,3,4,5,6,7,8,9]; //Edge case: the only one where '0' qualifies
const DFS = strnum => { //given some string representing a number strnum, build the string further using digits 0-9 in a way that the string satisfies the K difference rule
if (strnum.length === N){ //if length N is reached, add to ans if not previously encountered
const num = parseInt(strnum);
if (!ans.includes(num)) ans.push(num);
return;
}
const lastdigit = parseInt(strnum.slice(-1));
if (lastdigit + K <= 9) DFS(strnum+(lastdigit+K).toString()); //continue building the number string until length = N using the two options that satisfy the K difference rule
if (lastdigit - K >= 0) DFS(strnum+(lastdigit-K).toString());
return;
}
for (let i = 1; i <= 9; i++) DFS(i.toString()); //Launch DFS off of all possible first digits (zero is not one, but the extension DFS function accounts for possibility of zero usage in the middle or on the end)
return ans;
};
Approach) Depth First Search / BackTracking
let n, k, res;
const numsSameConsecDiff = (N, K) => {
n = N;
k = K;
res = new Set();
dfs('');
return [...res];
};
const dfs = (cur) => {
if (cur.length > n) return;
if (cur.length == n && ok(cur)) res.add(cur);
let start = cur.length == 0 ? 1: 0;
for (let i = start; i < 10; i++) { // build '0-9' string
cur += i + '';
if (ok(cur)) { // ok, dfs further
dfs(cur);
cur = cur.slice(0, -1); // backtracking, withdraw last digit
} else {
cur = cur.slice(0, -1); // not ok, no need to dfs further, but change last digit and continue
}
}
};
const ok = (s) => { // check consective absolute difference is all same
if (s.length == 1) return true;
if (s[0] == '0') return false;
let n = s.length, diff = Math.abs((s[1] - '0') - (s[0] - '0'));
if (diff != k) return false;
for (let i = 2; i < n; i++) {
let d = Math.abs((s[i] - '0') - (s[i - 1] - '0'));
if (d != k) return false;
}
return true;
};
Approach) Binary Solution
- I assume there will be 2^(N-1) maximum cases
- I make map of all N-1 length numbers in 2 base systems: for example, for N=3, [[0,0],[1,0],[0,1],[1,1] is the map;
- in the map, 0 means '+', 1 means '-'.
- for each digit from 1 to 9, I put the cases and checked each element is in [0,9] or not
var numsSameConsecDiff = function(N, K) {
let b=Array.apply(null, Array(N-1)).map(function(){return 0}); // set all elements to 0
let a = [];
a.push(b);
for(let i=1;i<=Math.pow(2,N-1);i++) {
let q=1; let c=[]; // add one to create new value of map
for(let j=0;j<N-1; j++) {
let sum = b[j]+q;
c.push(Math.ceil(sum%2));
q = Math.floor(sum/2);
}
b=c;
a.push(c);
}
let ans=[];
for(let s=1;s<10;s++) { // [1,9] starting digits
for(let i=1;i<=Math.pow(2,N-1);i++) {
let valid=true;
b = [s];c=''+s;
for(let j=1;j<N; j++) {
if(a[i][j-1]==0) { // choosing operators
b[j]=b[j-1]+K;
}
else {
b[j]=b[j-1]-K;
}
if(b[j]<0||b[j]>9) {
valid=false;
break;
}
c+=''+b[j];
}
if(valid) {
if(ans.indexOf(Number(c))==-1)ans.push(Number(c));
}
}
}
return ans;
};
Conclusion
That’s all folks! In this post, we solved LeetCode problem #967. Numbers With Same Consecutive Differences
I hope you have enjoyed this post. Feel free to share your thoughts on this.
You can find the complete source code on my GitHub repository. If you like what you learn. feel free to fork 🔪 and star ⭐ it.
In this blog, I have tried to collect & present the most important points to consider when improving Data structure and logic, feel free to add, edit, comment, or ask. For more information please reach me here
Happy coding!
Comments
Post a Comment