zoukankan      html  css  js  c++  java
  • [LeetCode] 5081. 步进数

    传送门:[LeetCode] 5081. 步进数

    题目描述

    如果一个整数上的每一位数字与其相邻位上的数字的绝对差都是 1,那么这个数就是一个「步进数」。

    例如,321 是一个步进数,而 421 不是。

    给你两个整数,lowhigh,请你找出在 [low, high] 范围内的所有步进数,并返回 排序后 的结果。

    示例 :

    输入:low = 0, high = 21
    输出:[0,1,2,3,4,5,6,7,8,9,10,12,21]

    提示:

    • 0 <= low <= high <= 2 * 10^9

    分析与代码

    • 一开始想到的是先把所有步进数求出来放到一个集合,然后再遍历取其中>=low && <= high的数添加到结果集合 result,最后排下序。
    • 求步进数是用 DFS 的方法,以 1 到 9 开头,每次把当前数乘 10 加上个位数加 1 或减 1。注意一下个位为 0 和 9 的特殊情况就好。
    • 0 特殊处理。

    代码:

    class Solution {
        public List<Integer> countSteppingNumbers(int low, int high) {
            List<Integer> list = new ArrayList<>();
            list.add(0);
            for (int i = 1; i <= 9; i++) {
                dfs(list, i);
            }
            List<Integer> result = new ArrayList<>();
            for (int num : list) {
                if (num >= low && num <= high) {
                    result.add(num);
                }
            }
            Collections.sort(result);
            return result;
        }
    
        public void dfs(List<Integer> list, int cur) {
            list.add(cur);
            if (cur > Integer.MAX_VALUE / 10) {
                return;
            }
            int r = cur % 10;
            if (r != 9) {
                dfs(list, cur * 10 + r + 1);
            }
            if (r != 0) {
                dfs(list, cur * 10 + r - 1);
            }
        }
    }
    

    解法一、DFS

    • 可以不求出所有结果,只在小于 high 范围内递归,在 DFS 过程中只添加符合要求的结果。

    代码:

    class Solution {
        public List<Integer> countSteppingNumbers(int low, int high) {
            List<Integer> result = new ArrayList<>();
            if (low == 0) {
                result.add(0);
            }
            for (int i = 1; i <= 9; i++) {
                dfs(result, i, low, high);
            }
            Collections.sort(result);
            return result;
        }
    
        public void dfs(List<Integer> result, int cur, int low, int high) {
            if (cur >= low && cur <= high) {
                result.add(cur);
            }
            if (cur > high / 10) {
                return;
            }
            int r = cur % 10;
            if (r != 9 && cur * 10 + r + 1 <= high) {
                dfs(result, cur * 10 + r + 1, low, high);
            }
            if (r != 0 && cur * 10 + r - 1 <= high) {
                dfs(result, cur * 10 + r - 1, low, high);
            }
        }
    }
    

    解法二、BFS

    • 先把 1 到 9 添加到队列,然后每次取出队列中的数,符合要求就添加到结果集合 result,并把下一位范围内的步进数加到队列。

    代码:

    class Solution {
        public List<Integer> countSteppingNumbers(int low, int high) {
            Queue<Integer> queue = new LinkedList<>();
            List<Integer> result = new ArrayList<>();
            if (low == 0) {
                result.add(0);
            }
            for (int i = 1; i <= 9; i++) {
                queue.offer(i);
            }
            while (!queue.isEmpty()) {
                int cur = queue.poll();
                if (cur >= low && cur <= high) {
                    result.add(cur);
                }
                if (cur > high / 10) {
                    continue;
                }
                int r = cur % 10;
                if (r != 9 && cur * 10 + r + 1 <= high) {
                    queue.offer(cur * 10 + r + 1);
                }
                if (r != 0 && cur * 10 + r - 1 <= high) {
                    queue.offer(cur * 10 + r - 1);
                }
            }
            Collections.sort(result);
            return result;
        }
    }
    

    小结

    就是以 1 到 9 开头,求出步进数,可以用 DFS,也可以用 BFS。



    ┆ 然 ┆   ┆   ┆   ┆ 可 ┆   ┆   ┆ 等 ┆ 暖 ┆
    ┆ 而 ┆ 始 ┆   ┆   ┆ 是 ┆ 将 ┆   ┆ 你 ┆ 一 ┆
    ┆ 你 ┆ 终 ┆ 大 ┆   ┆ 我 ┆ 来 ┆   ┆ 如 ┆ 暖 ┆
    ┆ 没 ┆ 没 ┆ 雁 ┆   ┆ 在 ┆ 也 ┆   ┆ 试 ┆ 这 ┆
    ┆ 有 ┆ 有 ┆ 也 ┆   ┆ 这 ┆ 会 ┆   ┆ 探 ┆ 生 ┆
    ┆ 来 ┆ 来 ┆ 没 ┆   ┆ 里 ┆ 在 ┆   ┆ 般 ┆ 之 ┆
    ┆   ┆   ┆ 有 ┆   ┆   ┆ 这 ┆   ┆ 降 ┆ 凉 ┆
    ┆   ┆   ┆ 来 ┆   ┆   ┆ 里 ┆   ┆ 临 ┆ 薄 ┆
  • 相关阅读:
    AOP 和 前置通知,后置通知
    使用Spring 简化MyBatis
    核心一:DI
    环境搭建及创建对象方式及赋值(注入)
    核心一:IoC
    Spring框架简介
    判断两个矩形是否相交的4个方法
    计算旋转角度
    浅析adb命令
    如何选择开源许可证?
  • 原文地址:https://www.cnblogs.com/qiu_jiaqi/p/LeetCode-5081.html
Copyright © 2011-2022 走看看