Bootstrap

数据结构与算法

栈:1:编程语言中函数的调用

        2:操作系统中从用户态到内核寄存器的保存

        3:网络消息的处理。

demo1:20. 有效的括号 - 力扣(LeetCode)

class Solution
{
public:
    bool isValid(string s)
    {
        std::map<char, char> map = {
            {'(', ')'},
            {'[', ']'},
            {'{', '}'}};
        stack<char> stack;

        for (int i = 0; i < s.size(); i++)
        {
            if (s[i] == '(' || s[i] == '[' || s[i] == '{')
            {
                stack.push(s[i]);
            }
            else if (!stack.empty() && s[i] == map[stack.top()])
            {
                stack.pop();
            }
            else
            {
                return false;
            }
        }
        return stack.empty();
    }
};
class Solution:
    def isValid(self, s):
        dic = {'{': '}',  '[': ']', '(': ')'}  # 定义字典
        stack = []
        for c in s:
            if c in dic:
                stack.append(c)
            elif len(stack) != 0 and dic[stack[-1]] == c:
                stack.pop()
            else:
                return False
        return len(stack) == 0

demo2:

int solution(vector<int> size, vector<int> dir)
{
    stack<int> stack;
    stack.push(dir[0]);
    for (int i = 1; i < dir.size(); i++)
    {

        if (dir[i] == stack.top()) // 符号相同入栈
        {
            stack.push(dir[i]);
        }
        else
        {
            while (dir[i] == 0 && stack.top() == 1) // 符号不相同,
            {
                if (size[stack.top()] > size[i]) // 栈中元素大
                {
                    break;
                }
                else
                { // 栈中元素小,移除,如果栈大小为0,退出
                    stack.pop();
                    if (stack.empty())
                    {
                        stack.push(dir[i]);
                        break;
                    }
                }
            }
        }
    }
    return stack.size();
};

demo3

vector<int> FindRightSmall(vector<int> vec)
{
    stack<int> stack; // 单调递增栈
    vector<int> ret(vec.size());
    stack.push(0);
    for (int i = 1; i < vec.size(); i++)
    {
        if (vec[stack.top()] < vec[i]) // 当前元素大
        {
            stack.push(i);
        }
        else
        {
            while (!stack.empty() && vec[stack.top()] > vec[i]) // 当前元素小了,找到目标元素
            {
                ret[stack.top()] = i;
                stack.pop();
            }
            stack.push(i);
        }
    }

    while (!stack.empty())
    {
        ret[stack.top()] = -1;
        stack.pop();
    }
    return ret;
}
def FindRightSmall(vec):
    stack = []
    ret = [-1] * len(vec)
    stack.append(0)
    for iter in range(1, len(vec)):
        if (vec[stack[-1]] < vec[iter]):
            stack.append(iter)
        else:
            while (len(stack) != 0 and vec[stack[-1]] > vec[iter]):
                ret[stack[-1]] = iter
                stack.pop()
            stack.append(iter)

    while (len(stack) != 0):
        ret[stack[-1]] = -1
        stack.pop()
    return ret

demo4

vector<int> FindSmallNumber(vector<int> vec, int k)
{
    stack<int> stack; // 单调递增栈
    vector<int> ret(k);
    stack.push(0);
    for (int i = 1; i < vec.size(); i++)
    {
        if (vec[stack.top()] < vec[i]) // 如果右边的数大,放入
        {
            stack.push(i);
        }
        else
        {
            while (!stack.empty() && vec[stack.top()] > vec[i] && (stack.size() + vec.size() - i) > k) // 栈的个数加上剩余的元素大于k
            {
                stack.pop();
            }

            stack.push(i);
        }
    };

    while (stack.size() > k)
    {
        stack.pop();
    }
    for (int i = k - 1; i >= 0; i--)
    {
        ret[i] = vec[stack.top()];
        stack.pop();
    }

    return ret;
}
def FindSmallNumber(vec, k):
    stack = []
    ret = [0] * k
    stack.append(0)
    for iter in range(1, len(vec)):
        if (vec[stack[-1]] < vec[iter]):
            stack.append(iter)
        else:
            while (len(stack) != 0 and vec[stack[-1]] > vec[iter] and (len(stack) + len(vec)-iter > k)):
                stack.pop()

            stack.append(iter)

    while (len(stack) > k):
        stack.pop()
    for iter in range(k-1, -1, -1):
        ret[iter] = vec[stack[-1]]
        stack.pop()

    return ret

队列

demo1

102. 二叉树的层序遍历 - 力扣(LeetCode)

// 队列遍历
class Solution
{
public:
    vector<vector<int>> levelOrder(TreeNode *root)
    {
        if (root == nullptr)
        {
            return vector<vector<int>>();
        }

        vector<vector<int>> ret;
        vector<int> ret_index;
        queue<TreeNode *> que;
        que.push(root);
        while (!que.empty())
        {
            int size = que.size();
            for (int i = 0; i < size; i++)
            {
                TreeNode *cur = que.front();
                ret_index.push_back(cur->val);
                que.pop();

                if (cur->left != nullptr)
                {
                    que.push(cur->left);
                }
                if (cur->right != nullptr)
                {
                    que.push(cur->right);
                }
            }
            ret.push_back(ret_index);
            ret_index.clear();
        }
        return ret;
    }
};

// 顺序遍历
// vector遍历
class Solution
{
public:
    vector<vector<int>> levelOrder(TreeNode *root)
    {
        if (root == nullptr)
        {
            return vector<vector<int>>();
        }

        vector<vector<int>> ret;
        vector<int> ret_index;
        vector<TreeNode *> cur_level;
        vector<TreeNode *> next_level;

        if (root != nullptr)
        {
            cur_level.push_back(root);
        }

        while (!cur_level.empty())
        {
            for (auto iter : cur_level)
            {
                ret_index.push_back(iter->val);
                if (iter->left != nullptr)
                {
                    next_level.push_back(iter->left);
                };
                if (iter->right != nullptr)
                {
                    next_level.push_back(iter->right);
                };
            }
            ret.push_back(ret_index);
            ret_index.clear();
            cur_level = next_level;
            next_level.clear();
        }
        return ret;
    }
};

demo2 

622. 设计循环队列 - 力扣(LeetCode)

// 循环队列
// 放入元素rear+1,删除元素front+1
//[)
class MyCircularQueue
{
private:
    vector<int> que;
    int front = 0;
    int rear = 0;

public:
    MyCircularQueue(int k)
    {
        que.resize(k + 1);
    };

    bool enQueue(int value)
    {
        if (!isFull())
        {
            // 把元素放到rear位置
            que[rear] = value;
            // rear向后移动
            rear = (rear + 1) % que.size();
            return true;
        }
        else
        {
            return false;
        }
    };
    // 出队,不删除元素
    bool deQueue()
    {
        if (isEmpty())
        {
            return false;
        }
        else
        {
            front = (front + 1) % que.size();
            return true;
        }
    };

    int Front()
    {
        return isEmpty() ? -1 : que[front];
    };

    int Rear()
    {
        int tail = (rear + que.size() - 1) % que.size();
        return isEmpty() ? -1 : que[tail];
    };

    bool isEmpty()
    {
        return rear == front;
    };

    bool isFull()
    {
        return (rear + 1) % que.size() == front;
    };
};

demo3

239. 滑动窗口最大值 - 力扣(LeetCode)

// 非严格单调递减双端队列
class Solution
{
private:
    deque<int> que;
    vector<int> vec;

private:
    void DecreasingQueue(int index)
    {
        while (!que.empty() && vec[que.back()] <= vec[index])
        {
            que.pop_back();
        }
        que.push_back(index);
    }

public:
    vector<int> maxSlidingWindow(vector<int> &nums, int k)
    {
        vector<int> ret;
        // 单调递减队列
        vec = nums;
        for (int i = 0; i < k; i++)
        {
            DecreasingQueue(i);
        }
        ret.push_back(nums[que.front()]);
        for (int i = k; i < nums.size(); i++)
        {
            DecreasingQueue(i);
            // 第一个元素超过限制
            if (i - que.front() >= k)
            {
                que.pop_front();
            }
            ret.push_back(nums[que.front()]);
        };
        return ret;
    }
};

;