C#LeetCode刷题之#641-设计循环双端队列(Design Circular Deque)

C#LeetCode刷题之#641-设计循环双端队列(Design Circular Deque)

问题

设计实现双端队列。
你的实现需要支持以下操作:

MyCircularDeque(k):构造函数,双端队列的大小为k。
insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true。
insertLast():将一个元素添加到双端队列尾部。如果操作成功返回 true。
deleteFront():从双端队列头部删除一个元素。 如果操作成功返回 true。
deleteLast():从双端队列尾部删除一个元素。如果操作成功返回 true。
getFront():从双端队列头部获得一个元素。如果双端队列为空,返回 -1。
getRear():获得双端队列的最后一个元素。 如果双端队列为空,返回 -1。
isEmpty():检查双端队列是否为空。
isFull():检查双端队列是否满了。

MyCircularDeque circularDeque = new MyCircularDeque(3);    // 设置容量大小为3
circularDeque.insertLast(1);               // 返回 true
circularDeque.insertLast(2);              // 返回 true
circularDeque.insertFront(3);            // 返回 true
circularDeque.insertFront(4);            // 已经满了,返回 false
circularDeque.getRear();                    // 返回  32 -此处应为2,LeetCode官方翻译错误,2018-11-08
circularDeque.isFull();                         // 返回 true
circularDeque.deleteLast();                // 返回 true
circularDeque.insertFront(4);            // 返回 true
circularDeque.getFront();                   // 返回 4

提示:

  • 所有值的范围为 [1, 1000]
  • 操作次数的范围为 [1, 1000]
  • 请不要使用内置的双端队列库。

Design your implementation of the circular double-ended queue (deque).
Your implementation should support following operations:

MyCircularDeque(k): Constructor, set the size of the deque to be k.
insertFront(): Adds an item at the front of Deque. Return true if the operation is successful.
insertLast(): Adds an item at the rear of Deque. Return true if the operation is successful.
deleteFront(): Deletes an item from the front of Deque. Return true if the operation is successful.
deleteLast(): Deletes an item from the rear of Deque. Return true if the operation is successful.
getFront(): Gets the front item from the Deque. If the deque is empty, return -1.
getRear(): Gets the last item from Deque. If the deque is empty, return -1.
isEmpty(): Checks whether Deque is empty or not. 
isFull(): Checks whether Deque is full or not.

MyCircularDeque circularDeque = new MycircularDeque(3);    // set the size to be 3
circularDeque.insertLast(1);               // return true
circularDeque.insertLast(2);              // return true
circularDeque.insertFront(3);            // return true
circularDeque.insertFront(4);            // return false, the queue is full
circularDeque.getRear();                    // return 32 -此处应为2,LeetCode官方翻译错误,2018-11-08
circularDeque.isFull();                        // return true
circularDeque.deleteLast();               // return true
circularDeque.insertFront(4);            // return true
circularDeque.getFront();                  // return 4

Note:

  • All values will be in the range of [1, 1000].
  • The number of operations will be in the range of [1, 1000].
  • Please do not use the built-in Deque library.

示例

public class Program {

    public static void Main(string[] args) {
        var circularDeque = new MyCircularDeque(5);

        Console.WriteLine(circularDeque.InsertFront(7));
        Console.WriteLine(circularDeque.InsertLast(0));
        Console.WriteLine(circularDeque.InsertLast(3));
        Console.WriteLine(circularDeque.InsertFront(9));

        Console.WriteLine(circularDeque.DeleteLast());
        Console.WriteLine(circularDeque.GetRear());

        Console.WriteLine();

        var circularDeque2 = new MyCircularDeque2(5);

        Console.WriteLine(circularDeque2.InsertFront(1));
        Console.WriteLine(circularDeque2.InsertLast(2));

        Console.WriteLine(circularDeque2.InsertLast(3));

        Console.WriteLine(circularDeque2.InsertFront(4));

        Console.WriteLine(circularDeque2.GetRear());
        Console.WriteLine(circularDeque2.IsFull());
        Console.WriteLine(circularDeque2.DeleteLast());
        Console.WriteLine(circularDeque2.GetRear());

        Console.WriteLine(circularDeque2.InsertFront(4));
        Console.WriteLine(circularDeque2.GetFront());

        Console.ReadKey();
    }

    public class MyCircularDeque {

        private int _frontIndex = -1;
        private int _rearIndex = -1;

        private int _count = 0;

        private List<int> _frontList = null;
        private List<int> _rearList = null;

        public MyCircularDeque(int k) {
            //构造函数,双端队列的大小为k
            _count = k;
            _frontList = new List<int>();
            _rearList = new List<int>();
        }

        public bool InsertFront(int value) {
            //将一个元素添加到双端队列头部。 如果操作成功返回 true
            if(_count == 0 || _frontIndex + _rearIndex == _count - 2) return false;
            _frontIndex++;
            _frontList.Add(value);
            return true;
        }

        public bool InsertLast(int value) {
            //将一个元素添加到双端队列尾部。如果操作成功返回 true
            if(_count == 0 || _frontIndex + _rearIndex == _count - 2) return false;
            _rearIndex++;
            _rearList.Insert(0, value);
            return true;
        }

        public bool DeleteFront() {
            //从双端队列头部删除一个元素。 如果操作成功返回 true
            if(_count == 0 || _frontIndex + _rearIndex == -2) return false;
            if(_frontIndex == -1) {
                _rearList.RemoveAt(_rearIndex);
                _rearIndex--;
                return true;
            }
            _frontList.RemoveAt(_frontIndex);
            _frontIndex--;
            return true;
        }

        public bool DeleteLast() {
            //从双端队列尾部删除一个元素。如果操作成功返回 true
            if(_count == 0 || _frontIndex + _rearIndex == -2) return false;
            if(_rearIndex == -1) {
                _frontIndex--;
                _frontList.RemoveAt(0);
                return true;
            }
            _rearIndex--;
            _rearList.RemoveAt(0);
            return true;
        }

        public int GetFront() {
            //从双端队列头部获得一个元素。如果双端队列为空,返回 -1
            if(_count == 0 || _frontIndex + _rearIndex == -2) return -1;
            if(_frontIndex == -1) {
                return _rearList[_rearIndex];
            }
            return _frontList[_frontIndex];
        }

        public int GetRear() {
            //获得双端队列的最后一个元素。 如果双端队列为空,返回 -1
            if(_count == 0 || _frontIndex + _rearIndex == -2) return -1;
            if(_rearIndex == -1) {
                return _frontList[0];
            }
            return _rearList[0];
        }

        public bool IsEmpty() {
            //检查双端队列是否为空
            return _frontIndex + _rearIndex == -2;
        }

        public bool IsFull() {
            //检查双端队列是否满了
            return _frontIndex + _rearIndex == _count - 2;
        }

    }

    public class MyCircularDeque2 {

        private List<int> _list = null;
        private int _count = 0;

        public MyCircularDeque2(int k) {
            _list = new List<int>();
            _count = k;
        }

        public bool InsertFront(int value) {
            if(_count > _list.Count) {
                _list.Insert(0, value);
                return true;
            }
            return false;
        }

        public bool InsertLast(int value) {
            if(_count > _list.Count) {
                _list.Add(value);
                return true;
            }
            return false;
        }

        public bool DeleteFront() {
            if(_list.Count > 0) {
                _list.RemoveAt(0);
                return true;
            }
            return false;
        }

        public bool DeleteLast() {
            if(_list.Count > 0) {
                _list.RemoveAt(_list.Count - 1);
                return true;
            }
            return false;
        }

        public int GetFront() {
            return _list.Count > 0 ? _list[0] : -1;
        }

        public int GetRear() {
            return _list.Count > 0 ? _list[_list.Count - 1] : -1;
        }

        public bool IsEmpty() {
            return _list.Count <= 0;
        }

        public bool IsFull() {
            return _list.Count == _count;
        }

    }

}

以上给出2种算法实现,以下是这个案例的输出结果:

True
True
True
True
True
0

True
True
True
True
3
False
True
2
True
4

分析:

显而易见,以上2种算法中所有的方法的时间复杂度均为: O(n)

本文由 .Net中文网 原创发布,欢迎大家踊跃转载。

转载请注明本文地址:https://www.byteflying.com/archives/4132

发表评论

登录后才能评论