查找具有不同数字的年份 - CCC 2013

时间:2017-07-15 19:19:49

标签: java stack

Python中的类似问题has been asked但是我使用Java和Java并没有内置字符串计数。

(这里是Python的答案:http://mmhs.ca/ccc/2013/ccc2013j3.txt

到目前为止,我有一个扫描仪包要求输入,然后我使用链接列表和堆栈来获取" x"数字整数的数量,并将整数分成单独的数字。

在这里我被卡住了,我无法从Stack.pop()获取输出并将每个单独的整数放入一个新变量中进行比较操作。

我尝试使用堆栈执行此操作,但在digit[i] = stack.pop()部分遇到错误。

有人能指出我在正确的方向吗?我可以从one列开始将每个数字递增1,但这会减慢代码速度,并且条件将永远运行/耗尽大量内存。

以下是代码:

LinkedList<Integer> stack = new LinkedList<>();
while (yeardigits > 0) {
    stack.push( yeardigits % 10 );
    yeardigits = yeardigits / 10;
}

while (!stack.isEmpty()) {
    System.out.println(stack.pop());

    for (int i = 1; i <= digitstot; i++) {
        int keeptrack = 0;
        keeptrack++;
        // digit[i] = stack.pop();
        System.out.println(digit[i]);
        digit[i] = keeptrack;
    }
}

1 个答案:

答案 0 :(得分:0)

我不确定您要使用链接列表实现的目标。一个直接的解决方案是将给定数量增加1并检查结果是否仅包含不同的数字。如果是这样,那么你找到了解决方案。如果不是,请执行下一次迭代。这可以这样实现:

public class NumberFinder {
    public static void main(String[] args) {
        long number = 10L;
        while (number++ <= 9876543210L) {
            if (hasDistinctDigits(String.valueOf(number))) {
                System.out.println("Next number: " + number);
                return;
            }
        }
        System.out.println("No bigger number possible");
        return;
    }

    private static boolean hasDistinctDigits(String number) {
        if (number.length() == 1) {
            return true;
        }
        String rest = number.substring(1);
        if (rest.contains(number.substring(0,1))) {
            return false;
        }
        return hasDistinctDigits(rest);
    }
}

该解决方案效率很低,因为它可能会循环很多次并创建大量字符串。它仍然在任何现代计算机上执行一两秒钟。

如果您正在寻找效率,那么应该使用更高级的算法。您可以从数字中的最高位置到最低位置开始搜索重复数字的数字。如果没有找到,你就完成了。如果找到一个,则增加该位置的数字,并将较低位置的所有数字设置为最低可能值。当您增加数字9时需要特别小心,您需要在更高位置增加数字。这是相当有效的,因为它只使用一个主循环(少于10个)使用单个数组来存储数字,但需要更多的代码。

public class NumberFinder1 {
    public static void main(String[] args) {
        long number = 9876543208L;

        if (number > 9876543210L || number < 0) {
            throw new IllegalArgumentException("Number to big or too small: " + number);
        }
        MyNumber myNumber = new MyNumber(++number);
        while (true) {
            int highestIndexOfDuplicateDigit = myNumber.getHighestIndexOfDuplicateDigit();
            if (highestIndexOfDuplicateDigit == -1) {
                System.out.println(myNumber.toString());
                return;
            }
            myNumber.increaseDigitAtPosition(highestIndexOfDuplicateDigit);
        }
    }

    private static class MyNumber {
        int[] digits = new int[10];
        int numberOfDigits;

        public MyNumber(long number) {
            while (numberOfDigits < 10 && number > 0) {
                digits[numberOfDigits] = (int) (number % 10);
                number = number / 10;
                numberOfDigits++;
            }
        }

        public int getHighestIndexOfDuplicateDigit() {
            return getHighestIndexOfDuplicateDigit(0, numberOfDigits - 1);
        }

        public int getHighestIndexOfDuplicateDigit(int from, int to) {
            if (from == to) {
                return -1;
            }
            for (int i = to - 1; i >= from; i--) {
                if (digits[to] == digits[i]) {
                    return i;
                }
            }
            return getHighestIndexOfDuplicateDigit(from, to - 1);
        }

        public void increaseDigitAtPosition(int index) {
            if (digits[index] < 9) {
                digits[index]++;
                for (int i = index - 1; i >= 0; i--) {
                    digits[i] = index - 1 - i;
                }
            } else {
                increaseDigitAtPosition(++index);
                if (index == numberOfDigits) {
                    numberOfDigits++;
                }
            }
        }

        @Override
        public String toString() {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = numberOfDigits - 1; i >= 0; i--) {
                stringBuilder.append(digits[i]);
            }
            return stringBuilder.toString();
        }
    }
}