2021-02-23 连续差相同的数字

题目 连续差相同的数字

返回所有长度为 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];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值