Java 一种邻接数字优化算法

Java 一种邻接数字优化算法,java,Java,给我两个整数'n'和'm',我必须找到[n,m]范围内的所有步进数。如果所有相邻数字的绝对差为2,则称为步进数。131是一个步进数,而421不是。我面临的问题是,我必须按排序顺序打印它们,不能重复从最小到最大的数字,但我的算法会随机打印它们,而且M的最大值可以是10^30,当设置时,我的程序内存不足。有什么建议吗 import java.util.*; class Main { public static void bfs(Long n, Long m, Long num) { Q

给我两个整数'n'和'm',我必须找到[n,m]范围内的所有步进数。如果所有相邻数字的绝对差为2,则称为步进数。131是一个步进数,而421不是。我面临的问题是,我必须按排序顺序打印它们,不能重复从最小到最大的数字,但我的算法会随机打印它们,而且M的最大值可以是10^30,当设置时,我的程序内存不足。有什么建议吗

import java.util.*;

class Main {

public static void bfs(Long n, Long m, Long num) {

    Queue<Long> q = new LinkedList<Long>();

    q.add(num);

    while (!q.isEmpty()) {

        Long stepNum = q.poll();

        if (stepNum <= m && stepNum >= n) {

            System.out.print(stepNum+" ");
        }

        if (stepNum == 0 || stepNum > m)
            continue;

        Long lastDigit = stepNum % 10;

        Long stepNumA = stepNum * 10 + (lastDigit - 2);
        Long stepNumB = stepNum * 10 + (lastDigit + 2);

        if (lastDigit == 0)
            q.add(stepNumB);

        else if (lastDigit == 9)
            q.add(stepNumA);

        else {
            q.add(stepNumA);
            q.add(stepNumB);
        }
    }
}

public static void displaySteppingNumbers(Long n, Long m) {

    for (Long i = (long) 0; i <= 9; i++)
        bfs(n, m, i);
}

// Driver code
public static void main(String args[]) {
    Long n = (long) 1;
    Long m = (long) Math.pow(10, 16);


    displaySteppingNumbers(n, m);

}
}
import java.util.*;
班长{
公共静态无效bfs(长n、长m、长num){
队列q=新的LinkedList();
q、 添加(num);
而(!q.isEmpty()){
Long stepNum=q.poll();
如果(stepNum=n){
系统输出打印(stepNum+“”);
}
如果(stepNum==0 | | stepNum>m)
持续
Long lastDigit=stepNum%10;
长stepNumA=stepNum*10+(最后一位数字-2);
长步数=步数*10+(最后一位数+2);
如果(最后一位==0)
q、 添加(stepnub);
else if(最后一位==9)
q、 添加(stepNumA);
否则{
q、 添加(stepNumA);
q、 添加(stepnub);
}
}
}
公共静态无效显示步进编号(长n,长m){

对于(Long i=(Long)0;i我相信您可能已经考虑过了。我将从一个方法开始,以确定单个
Long
是否为步进数。使用
String.valueOf(Long)
获取
字符串
表示形式,然后迭代该
字符串
中的字符,比较相邻值。如果两个数字的绝对差不是两个,则返回false。检查所有数字后,默认为
true
。如

private static boolean isSteppingNumber(long v) {
    char[] arr = String.valueOf(v).toCharArray();
    for (int i = 0; i + 1 < arr.length; i++) {
        // The - '0' is really only useful for debugging.
        int a = arr[i] - '0', b = arr[i + 1] - '0';
        if (Math.abs(b - a) != 2) {
            return false;
        }
    }
    return true;
}
接下来是从
n
m
的循环(我更喜欢原语
long
类型)


你有一个正确的想法,你可以像搜索图表一样搜索数字。但是为了让它们按正确的顺序排列,我建议使用最小优先级队列而不是队列

您的实现还有一个问题-您没有正确检查邻接的界限,例如,如果lastDigit大于7,则lastDigit+2不相邻

import java.util.*;

public class Main {

    public static void displaySteppingNumbers(Long m, Long n) {
        PriorityQueue<Long> heap = new PriorityQueue<>();
        for (Long i = 1L; i <= 9L; i++) {
            heap.add(i);
        }

        while (heap.peek() <= n) {
            Long steppingNumber = heap.poll();
            System.out.println(steppingNumber);
            Long lastDigit = steppingNumber % 10;
            if (lastDigit >= 2)
                heap.add(steppingNumber * 10 + lastDigit - 2);
            if (lastDigit <= 7)
                heap.add(steppingNumber * 10 + lastDigit + 2);
        }
    }


    public static void main(String []args){
        Long m = 100L;
        Long n = 300L;

        displaySteppingNumbers(m, n);
    }
}
import java.util.*;
公共班机{
公共静态无效显示步进编号(长m,长n){
PriorityQueue heap=new PriorityQueue();

对于(长i=1L;i请在将来发布pseudo。 以下是程序中前1000个数字的输出:

1 9 13 97 131 135 975 979 
2 20 24 202 242 246 
3 31 35 309 313 353 357 
4 42 46 420 424 464 468 
5 53 57 531 535 575 579 
6 64 68 642 646 686 690 
7 75 79 753 757 797 
8 86 90 864 868 902 
9 97 975 979 
我只是在每次bfs呼叫之前添加了一个
/n

这实际上是一个有趣的小谜题
写出一组数字的输出
您将找到一个二进制链接,其中0表示
序列中减量为2,序列中为1,增量为2
序列,即编号131357可以写成:
110111
然后您只需找到介于

给定范围,这就是您的解决方案:D

运行此代码时,我的第一个观察结果是,它生成的数字不是步进数字(例如1309)。删除这些数字可能会有所帮助。为什么要向队列中添加内容?一个简单的顺序
循环范围
[n,m]
和一个简单的函数
boolean isSteppingNumber(long num)
需要0内存并按顺序打印所有内容。我不确定这个“问题”的“答案”是什么样子,除了扔掉代码并向您展示正确的实现(在写这篇文章的时候,第一个答案出现了,就是这么做的…)。甚至不清楚你在那里尝试了哪种方法,BFS应该扮演什么角色……这是可行的,但我如何优化时间,似乎是一种蛮力,如果我错了就纠正我?),以及
import java.util.*;

public class Main {

    public static void displaySteppingNumbers(Long m, Long n) {
        PriorityQueue<Long> heap = new PriorityQueue<>();
        for (Long i = 1L; i <= 9L; i++) {
            heap.add(i);
        }

        while (heap.peek() <= n) {
            Long steppingNumber = heap.poll();
            System.out.println(steppingNumber);
            Long lastDigit = steppingNumber % 10;
            if (lastDigit >= 2)
                heap.add(steppingNumber * 10 + lastDigit - 2);
            if (lastDigit <= 7)
                heap.add(steppingNumber * 10 + lastDigit + 2);
        }
    }


    public static void main(String []args){
        Long m = 100L;
        Long n = 300L;

        displaySteppingNumbers(m, n);
    }
}
1 9 13 97 131 135 975 979 
2 20 24 202 242 246 
3 31 35 309 313 353 357 
4 42 46 420 424 464 468 
5 53 57 531 535 575 579 
6 64 68 642 646 686 690 
7 75 79 753 757 797 
8 86 90 864 868 902 
9 97 975 979