算法基础 典型题(一)栈/队列/堆

记录算法基础题思路:

step1:

队列实现栈:https://leetcode-cn.com/problems/implement-stack-using-queues/

使用队列实现栈的下列操作:
push(x) -- 元素 x 入栈
pop() -- 移除栈顶元素
top() -- 获取栈顶元素
empty() -- 返回栈是否为空

    /** Push element x onto stack. */
    void push(int x) {
        unsigned int size = que.size();
        que.push(x);
        while (size > 0) {
            que.push(que.front());
            que.pop();
            size--;
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int val = que.front();
        que.pop();
        return val;
    }
    
    /** Get the top element. */
    int top() {
        return que.front();
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        return  que.empty();
    }

算法基础 典型题(一)栈/队列/堆_第1张图片

 

栈实现队列:https://leetcode-cn.com/problems/implement-queue-using-stacks/

使用栈实现队列的下列操作:
push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。

   /** Push element x to the back of queue. */
    void push(int x) {
        pushStack.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        if (popStack.empty() == true) {
            int size = pushStack.size();
            while (size > 0) {
                int val = pushStack.top();
                pushStack.pop();
                popStack.push(val);
                size--;
            }
        }

        if (popStack.empty() != true) {
            int val = popStack.top();
            popStack.pop(); 
            return val;          
        }

        return -1;
    }
    
    /** Get the front element. */
    int peek() {
        if (popStack.empty() == true) {
            int size = pushStack.size();
            while (size > 0) {
                int val = pushStack.top();
                pushStack.pop();
                popStack.push(val);
                size--;
            }
        }
        if (popStack.empty() != true) {
            int val = popStack.top();
            return val;          
        }
        return -1;
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        if (pushStack.empty() == true && popStack.empty() == true) {
            return true;
        }
        return false;
    }

算法基础 典型题(一)栈/队列/堆_第2张图片

包含min函数栈:https://leetcode-cn.com/problems/min-stack/

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

   void push(int x) {
        if (x <= min) {
            dataStack.push(min);
            min = x;
        }
        dataStack.push(x);
    }
    
    void pop() {
        int val = dataStack.top();
        dataStack.pop();
        if (val == min) {
            min = dataStack.top();
            dataStack.pop();
        }
    }
    
    int top() {
        return dataStack.top();
    }
    
    int getMin() {
        if (dataStack.empty() == true) {
            return -1;
        }
        return min;
    }

算法基础 典型题(一)栈/队列/堆_第3张图片

合法出栈校验:https://leetcode-cn.com/problems/validate-stack-sequences/

给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。

    bool validateStackSequences(vector& pushed, vector& popped) {
        unsigned int pop_pos = 0;
        for (unsigned int i = 0; i < pushed.size(); i++) {
            dataStack.push(pushed[i]);
            while ((dataStack.empty() != true) && (dataStack.top() == popped[pop_pos])) {
                dataStack.pop();
                pop_pos++;
            }
        }
        return dataStack.empty() == true;
    }

算法基础 典型题(一)栈/队列/堆_第4张图片

简单计算器:https://leetcode-cn.com/problems/basic-calculator/

实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格  。
示例:
输入: "1 + 1"
输出: 2

    int calculate(string s) {
        stack opr;
        stack num;
        num.push(0);
        int idx = 0;
        while(idx < s.size()){
            if(s[idx] == ' ')
                ++idx;
            else if(s[idx] == '(' || s[idx] == '+' || s[idx] == '-'){
                opr.push(s[idx]);
                ++idx;
            }
            else if(s[idx] == ')'){
                int sum = 0;
                while(opr.top() != '('){
                    char op = opr.top();
                    opr.pop();
                    int n = num.top();
                    num.pop();
                    sum += op=='+'? n: -n;
                }
                sum += num.top();
                num.pop();
                num.push(sum);
                opr.pop();
                ++idx;
            }
            else{
                unsigned int val = 0;
                while (s[idx] >= '0' && s[idx] <= '9') {
                    val = val * 10 + s[idx] - '0';
                    idx++;
                }
                num.push(val);
            }
        }
        int sum = 0;
        while(!opr.empty()){
            char op = opr.top();
            opr.pop();
            int n = num.top();
            num.pop();
            sum += op=='+'? n: -n;
        }
        return sum + num.top();
    }

求第K大数:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 :
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

    int findKthLargest(vector& nums, int k) {
        priority_queue,greater> small_heap;
        for(auto num:nums){
            if(small_heap.size() < k) {
                small_heap.push(num);            
            } else {
                if (num > small_heap.top()) {
                    small_heap.pop();
                    small_heap.push(num);
                }
            }
        }
        return small_heap.top();
    }

 

算法基础 典型题(一)栈/队列/堆_第5张图片

寻中位数:https://leetcode-cn.com/problems/find-median-from-data-stream/

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。

     /* 大顶堆 放小的一半,堆顶为最大值 */
    priority_queue, less> low_heap;
     /* 小顶堆 放大的一半,堆顶为最小值 */
    priority_queue, greater> high_heap;
public:
    // Adds a number into the data structure.
    void addNum(int num)
    {
        if (low_heap.empty() == true) {
            low_heap.push(num);
            return;
        }
        
        if (low_heap.size() == high_heap.size()) {
            /* 两堆数量一样多,按实际大小判断放哪一堆里面 */
            if (num > low_heap.top()) {
                high_heap.push(num);
            } else {
                low_heap.push(num);               
            }
        } else if (high_heap.size() > low_heap.size()) {
            /* 大的数比较多,优先放low堆,放不进去就把high的top换过来 */
            if (num <= high_heap.top()) {
                low_heap.push(num);
            } else {
                low_heap.push(high_heap.top());
                high_heap.pop();
                high_heap.push(num);
            }
        } else {
            /* 小的数比较多,优先放high堆,放不进去就把low的top换过来 */
            if (num >= low_heap.top()) {
                high_heap.push(num);
            } else {
                high_heap.push(low_heap.top());
                low_heap.pop();
                low_heap.push(num);
            }
        }
    }

    double findMedian()
    {
        if (low_heap.size() == high_heap.size()) {
            return (low_heap.top() + high_heap.top()) / 2.0;
        } else if (low_heap.size() > high_heap.size()) {
            return low_heap.top();
        } else {
            return high_heap.top();
        }
    }

算法基础 典型题(一)栈/队列/堆_第6张图片

你可能感兴趣的:(数据结构与算法)