栈、队列、双端队列、优先队列

栈、队列、双端队列、优先队列

栈和队列的基本实现和特性

1.Stack:先入后出;添加、删除皆为O(1)
2.查询为 O(n)

时间复杂度

方法 复杂度
Access O(n)
Search O(n)
Insertion O(1)
Deletion O(1)

成员函数

  • 元素访问
    • top 访问栈顶元素
  • 容量
    • empty 检查底层的容器是否为空
    • size 返回容纳的元素数
  • 修改器
    • push 向栈顶插入元素
    • emplace 于顶原位构造元素
    • pop 删除栈顶元素
    • swap 交换内容

      示例代码-Stack

    Stack<Integer> stack = new Stack<>();
    stack.push(1); 
    stack.push(2); 
    stack.push(3); 
    stack.push(4); 
    System.out.println(stack); 
    System.out.println(stack.search(4)); 
    stack.pop();
    stack.pop(); 
    Integer topElement = stack.peek(); 
    System.out.println(topElement); 
    System.out.println(" 3的位置 " + stack.search(3));

队列

1.Queue:先入先出;添加、删除皆为O(1)
2.查询为 O(n)

时间复杂度

方法 复杂度
Access O(n)
Search O(n)
Insertion O(1)
Deletion O(1)

成员函数

  • 元素访问
    • front 访问第一个元素
    • back 访问最后一个元素
  • 容量
    • empty 检查底层的容器是否为空
    • size 返回容纳的元素数
  • 修改器
    • push 像队列尾部插入元素
    • emplace 于尾部原位构造元素
    • pop 删除栈顶元素
    • swap 交换内容

      示例代码-Queue

    Queue<String> queue = new LinkedList<String>(); 
    queue.offer("one"); 
    queue.offer("two"); 
    queue.offer("three"); 
    queue.offer("four"); 
    System.out.println(queue); 
    String polledElement = queue.poll(); 
    System.out.println(polledElement); 
    System.out.println(queue); 
    String peekedElement = queue.peek(); 
    System.out.println(peekedElement); 
    System.out.println(queue); 
    while(queue.size() > 0) {
         System.out.println(queue.poll()); 
         } 

    扩展

  • 双端队列
    • 简单理解:两端可以进出的
    • 插入和删除都是O(1)操作
    • QueueDeque - double ended queue
  • 优先队列
    • 插入操作:O(1)
    • 取出操作:O(logN) - 按照元素的优先级取出
    • 底层具体实现的数据结构较为多样和复杂:heap、bst(二叉搜索树)、treap

示例代码-Deque

Deque<String> deque = new LinkedList<String>(); 
deque.push("a"); 
deque.push("b"); 
deque.push("c"); 
System.out.println(deque); 
String str = deque.peek(); 
System.out.println(str); 
System.out.println(deque); 
while (deque.size() > 0) {
       System.out.println(deque.pop()); 
       }
System.out.println(deque)

第二节 LeetCode实战题目

有效的括号

class Solution {
public:
    bool isValid(string s) {
        if(s.length()%2!=0) return false;//一但是奇数说明不是有效的括号
        map<char,char> wordbook;//建立哈希表
        wordbook.insert(map<char,char>::value_type(')','('));
        wordbook.insert(map<char,char>::value_type(']','['));
        wordbook.insert(map<char,char>::value_type('}','{'));
        stack<char> mystack;//建立栈
        for(int i=0;i<s.length();i++)
        {
            if(s[i]=='['||s[i]=='{'||s[i]=='(')//匹配到左括号
                mystack.push(s[i]);//放入栈中
            else if(s[i]==']'||s[i]=='}'||s[i]==')')//匹配到右括号
            {
                if(mystack.empty()) return false;
                //匹配到右括号,栈中应该存在左括号。否则就是无效的括号
                if(wordbook[s[i]]==mystack.top())//与栈顶元素进行匹配
                {
                    mystack.pop();//匹配成功删除栈顶元素
                    continue;
                }
                else return false;
            }
        }
        if(mystack.empty()) return true;//有效的括号到最后检测结束栈中应没有元素
        else return false;
    }
};

最小栈

class MinStack {
private:
    vector<pair<int,int>> nums; // <value,current min>
    
public:
    MinStack() {
        nums = {};
    }
    
    void push(int x) {
        if ( nums.size() > 0 )
            nums.push_back(make_pair(x,min(x,nums[nums.size()-1].second)));
        else
            nums.push_back(make_pair(x,x));
    }
    
    void pop() {
        if ( nums.size() > 0 )
            nums.resize(nums.size()-1);
    }
    
    int top() {
        return nums[nums.size()-1].first;
    }
    
    int getMin() {
        return nums[nums.size()-1].second;
    }
};
/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

滑动窗口最大值

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        if(k==0)return {};
        vector<int>res;
        deque<size_t>window;
        /*Init K integers in the list*/
        for (size_t i = 0; i < k; i++) {
            while (!window.empty()  && nums[i] > nums[window.back()]) {
                window.pop_back();
            }
            window.push_back(i);
        }
        res.push_back(nums[window.front()]);
        /*End of initialization*/
        for (size_t i = k; i < nums.size(); i++) {
            if (!window.empty() && window.front() <= i - k) {
                window.pop_front();
            }
            while (!window.empty() && nums[i] > nums[window.back()]) {
                window.pop_back();
            }
            window.push_back(i);
            res.push_back(nums[window.front()]);
        }
        return res;
    }
};

柱状图中最大的矩形

// 扩展一下横排宽度不一样的情况
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        stack<int> s;
        s.push(-1);
        int max_area = 0, height, width;
        for(int i = 0; i < heights.size(); ++i) {
            while(s.top() != -1 && heights[i] <= heights[s.top()]) {
                height = heights[s.top()];
                s.pop();
                width = i-s.top()-1;
                //cout<<"height:"<<height<<" width:" <<width<<endl;
                max_area = max(max_area, width*height);
                //cout<<max_area<<endl;
            }
            s.push(i);
        }
        while(s.top() != -1) {
            height = heights[s.top()];
            s.pop();
            width = heights.size() - s.top() - 1;
            max_area = max(max_area, width*height);
            //cout<<max_area<<endl;
        }
        return max_area;
    }
};

Design Circular Deque

class MyCircularDeque {
public:
    vector<int> q;
    int front,rear;
    /** Initialize your data structure here. Set the size of the deque to be k. */
    MyCircularDeque(int k) {
        q.resize(k,0); //resizing the vector(arraysize) with the given size k.
        front=-1; //intially front and rear both points to the -1 location as in case of circular queue happens.
        rear=-1;
    }
    
    /** Adds an item at the front of Deque. Return true if the operation is successful. */
    bool insertFront(int value) {
        if(isFull()){ //checking for queue is full or not.
            return false;
        }
        else{
            if(front==-1){ //in case we are pushing the element in the queue for the first time.
                insertLast(value);
            }
            else{
                front=(front+(q.size()-1))%q.size(); //by this formula front will move to the 1 pos back where it is currently if it is on 0th postion then it will take the last index (Nth) location of the array/vector. just use copy pen and tried this out.
                q[front]=value; //put the value in q of front newly location 
            }
        }
        return true;
    }
    
    /** Adds an item at the rear of Deque. Return true if the operation is successful. */
    bool insertLast(int value) {
        if(isFull()){ //checking for queue is full or not.
            return false;
        }
        else{
            if(front==-1){ //in case we are pushing the element in the queue for the first time.
                front=0;
            }
            rear=(rear+1)%q.size(); //move rear by 1 location after where it is currently. If rear is on Nth location of the index in the array then it will move to the 0th location of the array. Remember we have alreay checked for the array full cond. in above if condition.just use copy pen and tried out this formula. 
            q[rear]=value;
        }
        return true;
    }
    
    /** Deletes an item from the front of Deque. Return true if the operation is successful. */
    bool deleteFront() {
        if(isEmpty()){
            return false;
        }
        else{
            if(front==rear){ //if there is only 1 element in the queue.
                front=-1;
                rear=-1;
            }
            else{
                front=(front+1)%q.size();  //moving front by 1
            }
        }
        return true;
    }
    
    /** Deletes an item from the rear of Deque. Return true if the operation is successful. */
    bool deleteLast() {
        if(isEmpty()){
            return false;
        }
        else{
            if(front==rear){
                front=-1;
                rear=-1;
            }
            else{
                rear=(rear+(q.size()-1))%q.size();
            }
        }
        return true;
    }
    
    /** Get the front item from the deque. */
    int getFront() {
        if(isEmpty()){
            return -1;
        }
        return q[front];
    }
    
    /** Get the last item from the deque. */
    int getRear() {
        if(isEmpty()){
            return -1;
        }
        return q[rear];
    }
    
    /** Checks whether the circular deque is empty or not. */
    bool isEmpty() {
        if(front==-1 && rear==-1){
            return true;
        }
        return false;
    }
    
    /** Checks whether the circular deque is full or not. */
    bool isFull() {
        if((rear+1)%q.size()==front){
            return true;
        }
        return false;
    }
};


/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque* obj = new MyCircularDeque(k);
 * bool param_1 = obj->insertFront(value);
 * bool param_2 = obj->insertLast(value);
 * bool param_3 = obj->deleteFront();
 * bool param_4 = obj->deleteLast();
 * int param_5 = obj->getFront();
 * int param_6 = obj->getRear();
 * bool param_7 = obj->isEmpty();
 * bool param_8 = obj->isFull();
 */

Trapping Rain Water

class Solution {
public:
    int trap(vector<int>& height) {
        if (height.size() < 3) return 0;
        
        register int i = 0, j = height.size() - 1;
        register int leftMax = 0, rightMax = 0, water = 0;
        
        while (i <= j) {
            if (height[i] > leftMax) leftMax = height[i];
            if (height[j] > rightMax) rightMax = height[j];
            
            if (leftMax <= rightMax) {
                water += leftMax - height[i];
                ++i;
            } else {
                water += rightMax - height[j];
                --j;
            }        
        }
        
        return water;
    }
};

猜你喜欢

转载自www.cnblogs.com/liugangjiayou/p/12389385.html