题目 连续差相同的数字
返回所有长度为 n 且满足其每两个连续位上的数字之间的差的绝对值为 k 的 非负整数 。
请注意,除了 数字 0 本身之外,答案中的每个数字都 不能 有前导零。例如,01 有一个前导零,所以是无效的;但 0 是有效的。
你可以按 任何顺序 返回答案。
示例 1:
输入:n = 3, k = 7
输出:[181,292,707,818,929]
解释:注意,070 不是一个有效的数字,因为它有前导零。
示例 2:
输入:n = 2, k = 1
输出:[10,12,21,23,32,34,43,45,54,56,65,67,76,78,87,89,98]
示例 3:
输入:n = 2, k = 0
输出:[11,22,33,44,55,66,77,88,99]
方法1 递归
设置一个函数,传入数字、n值(此处的n表示剩余的仍需填写的数字个数)、k。
class Solution {
vector<int> vec;
public:
vector<int> numsSameConsecDiff(int n, int k) {
for(int i=1 ; i<10 ; i++)
{
int next1 = i%10-k;
int next2 = i%10+k;
if(next1 >= 0)
getSolution(i*10+next1,n-2,k);
if(next2 < 10&& next1 != next2)
getSolution(i*10+next2,n-2,k);
}
return vec;
}
void getSolution(int num, int n,int k)
{
//添加到头,加入数组
if(n == 0)
{
vec.push_back(num);
return;
}
//获取下一位的数字
//当前数字取个位 加减 k
int next1 = num%10-k;
int next2 = num%10+k;
//后面添加的数字如果再0-9范围内,则递归处理该数字
if(next1 >= 0)
getSolution(num*10+next1 , n-1 , k);
if(next2 < 10 && next1 != next2)
getSolution(num*10+next2 , n-1 , k);
}
};
方法2 队列
类似于树的层序遍历,相同个数的元素结点集合作为一层。
第一层是1-9 各个结点,将每个结点末尾数字 加减 k,作为每个结点的两个孩子。如果在0-9范围内,则加入队列;否则不加入。
另外,当一层处理结束,n减1,当n=1时,队列里存放的全是n位数,挨个抛出存入数组即可。
class Solution {
public:
vector<int> numsSameConsecDiff(int n, int k)
{
vector<int> vec;
queue<int> Q;
for(int i=1 ; i<10 ; i++)
Q.push(i);
while(n != 1)
{
int size = Q.size();
while(size--)
{
int num = Q.front();
if(k == 0)
Q.push(num*10 + num%10);
else
{
if(num%10+k < 10)
Q.push(num*10 + num%10+k);
if(num%10-k >= 0)
Q.push(num*10 + num%10-k);
}
Q.pop();
}
n--;
}
while(!Q.empty())
{
vec.push_back(Q.front());
Q.pop();
}
return vec;
}
};
方法3 数组
通过一个二位数组,第 i 层存的是全部的 i+1 位元素,第0层存储1-9的数字。
则该数组中 第i+1层元素均有第 i 层决定,逐层获取元素,最后返回第n-1层全部元素即可(即全部的n位数)
class Solution {
public:
vector<int> numsSameConsecDiff(int n, int k)
{
//二维数组
vector<vector<int>> dp(n);
//第0层存储0-9,表示全部1位数元素
dp[0] = {1,2,3,4,5,6,7,8,9};
//从1-n层,逐层获取元素
for(int i=1 ; i<n ; i++)
{
//遍历第i-1层,获取元素
for(int j=0 ; j<dp[i-1].size() ; j++)
{
//如果两位之间差为0,直接将i-1层的各个数字的后面添加相同对应数字即可
if(k == 0)
{
dp[i].push_back(dp[i-1][j]*10 + dp[i-1][j]%10);
continue;
}
//上一层数字末尾数 加减 k 在0-9范围内,则加到第i层数组
if(dp[i-1][j]%10+k < 10)
dp[i].push_back(dp[i-1][j]*10 + dp[i-1][j]%10+k);
if(dp[i-1][j]%10-k >= 0)
dp[i].push_back(dp[i-1][j]*10 + dp[i-1][j]%10-k);
}
}
//返回最后一层数组
return dp[n-1];
}
};