【问题标题】:Java palindrome checker using queue AND restoring queue to original stateJava回文检查器使用队列并将队列恢复到原始状态
【发布时间】:2014-06-18 19:49:49
【问题描述】:

我编写了一个冗长而复杂的方法来检查 Queue 中的元素列表是否为回文。我知道它可以改进,但我现在的目标是让它通过所有实践测试。我已经通过了 9 分(满分 10 分),但我似乎无法通过的唯一测试是奇数元素/不是回文。

例如: 前 [5, 10, -1, 4, 3, 2, 2, 4, -1, 10, 5] 后。预期输出应为 FALSE。我的输出是 TRUE。

此外,与其他测试不同,队列中的元素不会被显示。与之前提出的与此问题类似的问题不同,我的队列必须恢复到其原始状态。到目前为止,这是我的代码:

    public static boolean isPalindrome(Queue<Integer> q) {
        Stack<Integer> s = new Stack<Integer>();
        int size = q.size();
        int extra = 0;

        if(q.isEmpty()) 
            return true;
        else 
            if (size % 2 == 0) {
                for (int i = 0; i < size / 2; i++) {
                    s.push(q.remove());
                }      
            while (!s.isEmpty()) {  // While Stack is not empty:
                if (s.peek() != q.peek()) {
                    int first = s.pop();
                    s.push(q.remove());
                    s.push(first);

                    while (!q.isEmpty())
                        s.push(q.remove());

                    while (!s.isEmpty()) {
                        q.add(s.pop());
                    }
                    return false;
                }
            else {
                while (!q.isEmpty())
                    s.push(q.remove());

                while (!s.isEmpty()) {
                    q.add(s.pop());  // Restore Queue to original order
                }
                return true;
            }
        }

        for (int k = 0; k < size / 2; k++) {
            q.add(q.remove());
            s.push(q.remove());
        }

        for (int l = 0; l < size / 2; l++)
            s.push(q.remove());

        while (!s.isEmpty())
            q.add(s.pop());
    }
    return true;
}

如果有人在阅读本文时遇到困难,或者可以提出一种方法来减少它的复杂性,我将不胜感激。谢谢,对于臃肿的代码再次抱歉。

【问题讨论】:

  • 检查回文的复杂代码很多
  • @Cruncher 同意了。为什么不直接将元素转换为字符串并使用 StringBuilder.reverse() 和一个很好的旧 .equals() 比较?
  • @MarkW 还有比这更有效、更通用的解决方案。在这种情况下,实际上并不是那么简单,因为 [21, 25, 21] 如果你创建一个字符串是“212521”,如果你反转你会得到“125212”,这与原来的非常不同。但是只要有一个列表并不断比较索引i 和索引length-i-1 就可以了。适用于您可以调用 equals 的任何数据类型。
  • @Cruncher 是的,我忽略了这一点,所以 +1。
  • @Cruncher 该死的你和你无懈可击的逻辑!

标签: java stack queue palindrome


【解决方案1】:

为什么不使用过程中不关心是否破坏队列的简单算法,而是第一步复制队列呢?

public static boolean isPalindrome(Queue<Integer> q) {
    return isPalindromeDestructive(copyQueue(q));
}

private static boolean isPalindromeDestructive(Queue<Integer> q) {
    //Destructive algorithm that treats q as disposable.
}

private static Queue<Integer> copyQueue(Queue<Integer> q) {
    return new LinkedList<Integer>(q);
}

你可以随心所欲地实现 copyQueue,但这行得通。

【讨论】:

  • 对不起,我忘了补充一点,我们只能使用一个 Stack 作为辅助存储。
【解决方案2】:

Cruncher 我按照你的方式复制了队列。我担心奇怪大小的队列使代码过于复杂。我会投票赞成你的答案,因为这确实有帮助,但飞行常客里程不够。

真正要做的就是扔掉我第一次发布的旧东西,这有时是最好的。

不管怎样,就是这样。 for 循环加载堆栈,使复制 Cruncher 被提及。 while 循环只是在弹出堆栈时偷看然后重新加载队列。干净多了,我在问对问题后花了几分钟时间。

public static boolean isPalindrome(Queue<Integer> q) {
    Stack<Integer> s = new Stack<Integer>();
    int size = q.size();
    boolean palindrome = true;

    for (int i = 0; i < size; i++) {
        int value = q.peek();
        s.push(value);
        q.remove();
        q.add(value);
    }

    while (!s.isEmpty()) {
         if (s.peek() != q.peek())
            palindrome = false;
         s.pop();
         q.add(q.remove());
    }
    return palindrome;
}

【讨论】:

    猜你喜欢
    • 2019-07-07
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多