Design a stack with operations on middle element(设计一个操作中间元素的栈)

Design a stack with operations on middle element(设计一个操作中间元素的栈)

如何在O(1)的时间复杂度下实现支持以下操作的栈?

  • 1).push():将元素添加到栈顶部。

  • 2).pop():从栈顶部移除元素。

  • 3).findmidle():返回栈的中间元素。

  • 4).deleteMiddle():将删除中间元素。

推栈和弹栈是标准的栈操作。

重要的问题是,是否使用链表或数组来实现栈?

请注意,需要查找并删除中间元素。对于数组而言,从中间删除元素时间复杂度不是O(1)。此外,可能需要在push()时向上移动中间指针,在pop()时向下移动。在单链表中,无法在两个方向上移动中间指针。

其思想是使用双端链表(DLL)。通过维护中间指针,可以在O(1)时间内删除中间元素。可以使用previousnext指针在两个方向上移动中间指针。

下面是push()pop()findmidle()操作的实现。deleteMidle()的实现留作练习。如果栈中有偶数个元素,findmidle()将返回中间的第二个元素。例如,如果栈包含{1,2,3,4},那么findmidle()将返回3。

Code:

static class _3rd {
    public static void main(String[] args) {
        _3rd handler = new _3rd();
        handler.test();
    }

    private void test() {
        MyStack myStack = new MyStack();
        myStack.push(11);
        myStack.push(22);
        myStack.push(33);
        myStack.push(44);
        myStack.push(55);
        myStack.push(66);
        myStack.push(77);
        System.out.println("Item popped is " + myStack.pop());
        System.out.println("Item popped is " + myStack.pop());
        System.out.println("Middle Element is " + myStack.findMiddle());
        System.out.println("Deleted Middle Element is  " + myStack.deleteMiddle());
        System.out.println("Middle Element is " + myStack.findMiddle());
    }


    class DLLNode {
        private DLLNode prev;
        private DLLNode next;
        private int data;

        public DLLNode(int data) {
            this.data = data;
        }
    }

    class MyStack {
        private DLLNode head;//头指针
        private DLLNode mid;//中间指针
        private int count;

        public MyStack() {
        }

        public void push(int data) {
            DLLNode node = new DLLNode(data);
            //当前的节点的next指针指向head 并将count++
            node.prev = null;
            node.next = head;
            count++;
            //如果只有一个元素,移动mid到当前节点
            if (count == 1) {
                mid = node;
            } else {//如果不止一个元素,将head指针的prev指针指向当前节点
                head.prev = node;
                if (count % 2 != 0) {//odd 奇数 移动mid指针
                    mid = mid.prev;
                }
            }
            //head指针前移
            head = node;
        }

        public int pop() {
            if (count == 0) {
                System.out.println("Stack is empty!");
                return -1;
            }
            int item = head.data;
            //移动head指针到下一个节点
            head = head.next;
            //head指针不为空的时候,prev指针置为空
            if (head != null) {
                head.prev = null;
            }
            count--;
            if (count % 2 == 0) {//数量-1 ,偶数时,移动到当前mid的下一个节点
                mid = mid.next;
            }
            return item;
        }


        public int findMiddle() {
            if (count == 0) {
                System.out.println("Stack is empty!");
                return -1;
            }
            return mid.data;
        }


        public int deleteMiddle() {
            if (count == 0) {
                System.out.println("Stack is empty!");
                return -1;
            }
            int item = mid.data;
            mid.next.prev = mid.prev;
            mid.prev.next = mid.next;
            mid = mid.next;
            count--;
            return item;

        }


    }
}

Reference

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值