简体   繁体   English

Java ArrayDeque push() 似乎添加到堆栈的前/尾 [潜在错误]

[英]Java ArrayDeque push() seems to add to front/tail of stack [potential bug]

I am working on leetcode question 84, maximal rectangles.我正在研究 leetcode 问题 84,最大矩形。 When testing, I come across this bizarre case where the stack seems to add to the tail.在测试时,我遇到了这种奇怪的情况,堆栈似乎添加到尾部。 I confirmed this using print statements and an iterator object.我使用打印语句和迭代器 object 确认了这一点。

The test case is: [4,2,0,3,2,5]测试用例是:[4,2,0,3,2,5]

The second to last element in the array, 2, appears to be pushed to the tail, right under 0 (It should be pushed to the top. In my print statements, val:x gap:y appears when an element is popped, xyz appears when an element is pushed, and added: x is what the iterator prints. The whole stack is iterated through at each increment through the array. Code is here. I'm sure just posting a blob of code like this is bad etiquette so feel free to provide some criticism.数组中倒数第二个元素 2 似乎被推到了尾部,正好在 0 下方(它应该被推到顶部。在我的打印语句中,val:x gap:y 在弹出元素时出现,xyz当一个元素被推入并添加时出现:x 是迭代器打印的内容。整个堆栈在数组的每个增量处被迭代。代码在这里。我确定只是发布这样的代码块是不好的礼仪,所以随时提供一些批评。

class Solution {
    public int largestRectangleArea(int[] heights) {
        //use a stack
        //if element is bigger than top of stack, than add element to stack
        //if element is same as top, add element to stack
        //if element is less than top, pop all elements and calculate areas, also keep track of area of new top
        
        Deque<Helper> myStack = new ArrayDeque<Helper>();
        
        if (heights.length == 0 || heights == null) return 0;
        if (heights.length == 1) return heights[0];
        
        int poppedLength = 0;
        int area;
        int maxArea = 0;
        Helper previous = new Helper(heights[0]);
        
        myStack.push(previous);
        
        for (int i = 1; i < heights.length; i++) { //iterate through input array
            Iterator<Helper> myIt = myStack.iterator();
            while (myIt.hasNext()) { //iterate through stack, for testing purposes
                System.out.print(myIt.next().toString());
                System.out.println();
            }
            if (!myStack.isEmpty()) {
                if (heights[i] >= myStack.peek().getValue()) {//if curr element is greater than last, push current element
                    myStack.push(new Helper(heights[i]));
                    System.out.print("added1: "); //testing print statements
                    System.out.println(heights[i]);
                } else {
                    while (heights[i] < myStack.peek().getValue()) { //if current element is less than head of stack, pop elements from stack until current is >= head of stack

                        Helper popped = myStack.pop();
                        poppedLength++;
                        
                        area = (poppedLength + popped.getGapLength()) * popped.getValue();
                        System.out.print(poppedLength + popped.getGapLength()); //print statements for testing
                        System.out.print("  ");
                        System.out.print(popped.getValue());
                        System.out.print("  ");
                        System.out.print(area);
                        System.out.println();
                        if (area > maxArea) maxArea = area; //update max

                        if (myStack.isEmpty()) break;

                        
                    }
                    if (!myStack.isEmpty()) {
                        myStack.peek().setGapLength(poppedLength + myStack.peek().getGapLength());

                    } 
                    
                    myStack.add(new Helper(heights[i], poppedLength)); //push current, THIS IS WHERE THE ERROR IS OCCURING
                    System.out.print("added2: ");
                    System.out.println(heights[i]);
                    
                    poppedLength = 0;
                }
            } else {//if stack is empty for some reason, this actually should never execute
                myStack.push(new Helper(heights[i]));
            }
        }
        
        while (!myStack.isEmpty()) {//remove rest of elements in the stack
            Helper popped = myStack.pop();
            poppedLength++;
            
            area = (poppedLength + popped.getGapLength()) * popped.getValue();
            if (area > maxArea) maxArea = area;
            
            System.out.print(poppedLength + popped.getGapLength());
            System.out.print("  ");
            System.out.print(popped.getValue());
            System.out.print("  ");
            System.out.print(area);
            System.out.println();
            
        }
        
        return maxArea;
    }
    
    class Helper {//the elements of the stack
    
        private int value;
        private int gapLength;

        public Helper(int val) {
            value = val;
            gapLength = 0;
        }
        
        public Helper(int val, int gap) {
            value = val;
            gapLength = gap;
        }

        public int getValue() {
            return value;
        }
        
        public int getGapLength() {
            return gapLength;
        }
        
        public void setGapLength(int length) {
            gapLength = length; 
        }
        
        public String toString() {
            String retStr = "Val: " + Integer.toString(value) + "    Gap:" + Integer.toString(gapLength) + "     ";
            return retStr;
        }
    }
}

The way you're approaching the problem, by breaking it into multiple functions, is good.通过将其分解为多个功能来解决问题的方式很好。 However, it's hard to debug for us.但是,我们很难调试。

This'd pass through:这会通过:

class Solution {
    public static int largestRectangleArea(int[] height) {
        if (height == null || height.length == 0) {
            return 0;
        }

        int[] leftReduce = new int[height.length];
        int[] rightReduce = new int[height.length];
        rightReduce[height.length - 1] = height.length;
        leftReduce[0] = -1;

        for (int i = 1; i < height.length; i++) {
            int p = i - 1;

            while (p >= 0 && height[p] >= height[i]) {
                p = leftReduce[p];
            }

            leftReduce[i] = p;
        }

        for (int i = height.length - 2; i >= 0; i--) {
            int p = i + 1;

            while (p < height.length && height[p] >= height[i]) {
                p = rightReduce[p];
            }

            rightReduce[i] = p;
        }

        int maxArea = 0;

        for (int i = 0; i < height.length; i++) {
            maxArea = Math.max(maxArea, height[i] * (rightReduce[i] - leftReduce[i] - 1));
        }

        return maxArea;
    }
}

Just like the comments under the question, I'm also a bit puzzled with this line:就像问题下的评论一样,我对这一行也有点困惑:

Deque<Helper> myStack = new ArrayDeque<Helper>();

References参考

  • For additional details, you can see the Discussion Board .有关其他详细信息,您可以查看讨论板 There are plenty of accepted solutions with a variety of languages and explanations, efficient algorithms, as well as asymptotic time / space complexity analysis 1 , 2 in there.有许多公认的解决方案,其中包含各种语言和解释、高效算法以及渐近时间/空间复杂度分析12

Since you are preparing for interviews :由于您正在准备面试

  • We would want to write bug-free and clean codes based on standards and conventions (eg, 1 , 2 , 1 , 2 , 1 , 2 , 1 , 2 , 1 , 1 , 1 , 1 ). We would want to write bug-free and clean codes based on standards and conventions (eg, 1 , 2 , 1 , 2 , 1 , 2 , 1 , 2 , 1 , 1 , 1 , 1 )。

  • The time to implement a solution during the interview is pretty limited.在面试期间实施解决方案的时间非常有限。 Make sure to not run out of time by complicating the design of your codes.确保不会因为代码设计复杂化而耗尽时间。

Good luck with your interviews!祝你面试顺利! ˆ_ˆ ^_^

I was not able to figure out exactly what my bug was but was able to fix the issue by calling the push() method instead of both the push() and add() methods.我无法确切地弄清楚我的错误是什么,但能够通过调用 push() 方法而不是 push() 和 add() 方法来解决问题。 I suspect that the methods rely on not being used interchangeably.我怀疑这些方法依赖于不能互换使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM