每日总结day23-25

目录

一、小论文修改

二、算法刷题

1、栈与队列

1)用栈实现队列

2)用队列实现栈

3)有效的括号

4)删除字符串中的所有相邻重复项

5)逆波兰表达式求值

6)滑动窗口最大值

7)前K个高频元素

2、二叉树

1)二叉树的递归遍历

1】前序遍历

2】中序遍历

3】后序遍历

2)二叉树的迭代遍历

三、openMMLab

1、主要内容

2、MMDetection项目概览

四、OneNote笔记工具

1、OneNote简介

2、笔记本的创建、保存与共享

3、笔记本的逻辑结构

4、小结

5、参考链接


 

一、小论文修改

二、算法刷题

1、栈与队列

1)用栈实现队列

力扣题目链接(opens new window)

使用栈实现队列的下列操作:

push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。

示例:

MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false

说明:

  • 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

 思路与注意点:

1】在这里需要两个栈分别模拟输入端和输出端。
2】这里pop()注意:分为stOut为空和不为空的情况,为空则表示第一次进行pop或peek。
3】这里peek函数中使用pop为基础获取开头元素后将值push回去时应该从stOut回去而非stIn,因为将值压回stIn顺序全乱了。

class MyQueue {
public:
    stack<int> stIn;
    stack<int> stOut;
    MyQueue() {

    }
    
    void push(int x) {
        stIn.push(x);
    }
    
    int pop() {
        //注意这里需要先判断一下stOut是否为空,为空则需要将stIn转存到stOut
        if(stOut.empty()){
            while(!stIn.empty()){
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        int res = stOut.top();
        stOut.pop();
        return res;
    }
    
    int peek() {
        int res = this->pop();
        stOut.push(res);
        return res;
    }
    
    bool empty() {
        return stIn.empty() && stOut.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

2)用队列实现栈

力扣题目链接(opens new window)

使用队列实现栈的下列操作:

  • push(x) -- 元素 x 入栈
  • pop() -- 移除栈顶元素
  • top() -- 获取栈顶元素
  • empty() -- 返回栈是否为空

注意:

  • 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
  • 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
  • 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

 思路:

一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。 

class MyStack {
public:
    queue<int> que;
    MyStack() {

    }
    
    void push(int x) {
        que.push(x);
    }
    
    int pop() {
        int size = que.size();
        size--;
        while(size--){
            que.push(que.front());
            que.pop();
        }
        int res = que.front();
        que.pop();
        return res;
    }
    
    int top() {
        return que.back();
    }
    
    bool empty() {
        return que.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

3)有效的括号

力扣题目链接(opens new window)

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 注意空字符串可被认为是有效字符串。

示例 1:

  • 输入: "()"
  • 输出: true
class Solution {
public:
    bool isValid(string s) {
        int size = s.size();
        if(size % 2 != 0) return false;
        stack<char> st;
        for(int i=0; i<size; i++){
            if(s[i] == '(') st.push(')');
            else if(s[i] == '{') st.push('}');
            else if(s[i] == '[') st.push(']');
            else if(st.empty() || st.top() != s[i]) return false;
            else st.pop();
        }
        // return true;
        return st.empty();
    }
};

4)删除字符串中的所有相邻重复项

力扣题目链接(opens new window)

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

  • 输入:"abbaca"
  • 输出:"ca"
  • 解释:例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

提示:

  • 1 <= S.length <= 20000
  • S 仅由小写英文字母组成。
class Solution {
public:
    string removeDuplicates(string s) {
        string res;
        for(char i : s){
            if(res.empty() || i != res.back()){
                res.push_back(i);
            }else{
                res.pop_back();
            }
        }
        return res;
    }
};

5)逆波兰表达式求值

力扣题目链接(opens new window)

根据 逆波兰表示法,求表达式的值。

有效的运算符包括 + ,  - ,  * ,  / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

示例 1:

  • 输入: ["2", "1", "+", "3", " * "]
  • 输出: 9
  • 解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<long long> st;
        for(int i=0; i<tokens.size(); i++){
            if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){
                // 注意:这里并没有将符号存入,因此不需要进行弹出操作
                // st.pop();
                long long nums1 = st.top();
                st.pop();
                long long nums2 = st.top();
                st.pop();
                if(tokens[i] == "+") st.push(nums2 + nums1);
                if(tokens[i] == "-") st.push(nums2 - nums1);
                if(tokens[i] == "*") st.push(nums2 * nums1);
                if(tokens[i] == "/") st.push(nums2 / nums1);
            }else{
                st.push(stoll(tokens[i]));
            }
        }
        long long res = st.top();
        return res;
    }
};

6)滑动窗口最大值

力扣题目链接(opens new window)

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

进阶:

你能在线性时间复杂度内解决此题吗?

 

提示:

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4
  • 1 <= k <= nums.length
class Myqueue{
// 注意需要添加public
public:  
    // queue<int> que;
    deque<int> que;
    void push(int value){
        while(!que.empty() && value > que.back()){
            que.pop_back();
        }
        // que.push(value);
        que.push_back(value);
    }
    void pop(int value){
        // while(!que.empty() && value == que.front()){
        //     // que.pop();
        //     que.pop_front();
        // }
        if(!que.empty() && value == que.front()){
            // que.pop();
            que.pop_front();
        }
    }
    int front(){
        return que.front();
    }
};

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        Myqueue que;
        vector<int> res;
        for(int i=0; i<k; i++){
            que.push(nums[i]);
        }
        res.push_back(que.front());
        for(int i=k; i<nums.size(); i++){
            que.pop(nums[i-k]);
            que.push(nums[i]);
            res.push_back(que.front());
        }
        return res;
    }
};

7)前K个高频元素

力扣题目链接(opens new window)

给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例 1:

  • 输入: nums = [1,1,1,2,2,3], k = 2
  • 输出: [1,2]

示例 2:

  • 输入: nums = [1], k = 1
  • 输出: [1]

提示:

  • 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
  • 你的算法的时间复杂度必须优于 $O(n \log n)$ , n 是数组的大小。
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
  • 你可以按任意顺序返回答案。
class Solution {
public:
    // bool compare()(const pair<int, int> &lhs, const pair<int, int> &rhs){
    //     return lhs.second() > rhs.second();
    // }
    class mycompare {
    public:
        bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {
            return lhs.second > rhs.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
        // priority_queue<pair<int, int>, vector<pair<int, int>>, compare> que;
        priority_queue<pair<int, int>, vector<pair<int, int>>, mycompare> que;
        unordered_map<int, int> map;
        // vector<int> res;
        vector<int> res(k);
        for(int i=0; i<nums.size(); i++){
            map[nums[i]]++;
        }

        // 错误写法,不能通过pair方式进行que赋值
        // for(int i=0; i<nums.size(); i++){
        //     // que.push(pair<nums[i], map[nums[i]]>);
        //     que.push(pair<nums[i], map[nums[i]]>);
        //     if(que.size() > k){
        //         que.pop();
        //     }
        // }
        //
        // 此种方法会导致错误:不仅多循环了几次,而且重复插入相同的节点,并未相比暴力解法少多少时间复杂度
        // 错误原因:这里相当于有多个重复的元素节点,其实每个pair(1,3),其实是同一个节点,而这里当成了不同的元素节点,因此这里就返回了前k个不同的pair(1,3)的节点,填入示例[1,1,1,2,2,3] 输出为[1,1]而非[1,2]这里手动推一下就清楚了。
        // for(int i=0; i<nums.size(); i++){
        //     // 注意:正确que中插入pair
        //     //     queue<pair<int,int>> q;
        //     //     q.push({1,2});
        //     //     q.push(make_pair(1,2));
        //     // 错误插入pair
        //     // que.push(pair<nums[i], map[nums[i]]>);
        //     que.push(make_pair(nums[i], map[nums[i]]));
        //     if(que.size() > k){
        //         que.pop();
        //     }
        // }

        // 用固定大小为k的小顶堆,扫描所有频率的数值
        for (unordered_map<int, int>::iterator it = map.begin(); it != map.end(); it++) {
            que.push(*it);
            if (que.size() > k) { // 如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
                que.pop();
            }
        }

        for(int i=k-1; i>=0; i--){
            // res.push_back(que[i].first());
            res[i] = que.top().first;
            que.pop();
        }
        return res;
    }
};

2、二叉树

1)二叉树的递归遍历

1】前序遍历

 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        st.push(root);
        vector<int> res;
        // 注意添加判断root是否为NULL
        if(root == NULL) return res;
        while(!st.empty()){
            TreeNode* node = st.top();
            st.pop();
            res.push_back(node->val);
            // 注意添加判断是否为节点left和right是否为空
            // st.push(node->right);
            // st.push(node->left);
            if(node->right) st.push(node->right);
            if(node->left) st.push(node->left);
        }
        return res;
    }
};

2】中序遍历

 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void midTrvel(TreeNode* cur, vector<int>& res){
        if(cur == NULL) return;
        midTrvel(cur->left, res);
        res.push_back(cur->val);
        midTrvel(cur->right, res);
    }

    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        midTrvel(root, res);
        return res;
    }
};

3】后序遍历

 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void backTravel(TreeNode *cur, vector<int> &res){
        if(cur == NULL) return;
        backTravel(cur->left, res);
        backTravel(cur->right, res);
        res.push_back(cur->val);
    }

    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        backTravel(root, res);
        return res;
    }
};

2)二叉树的迭代遍历

1】前序遍历

2】中序遍历

3】后序遍历

三、openMMLab

参考:5 MMDetection 代码教学_哔哩哔哩_bilibili

1、主要内容

1)MMDetection项目概览

2)MMDetection运行环境搭建(基于Openbayes计算平台)

3)使用MMDetection进行模型推理

4)使用MMDetection训练模型,检测图像中水果

2、MMDetection项目概览

1)目标检测工具包MMDetection

2)应用范围

3)MMDetection环境搭建

4)在线平台Openbayes

四、OneNote笔记工具

1、OneNote简介

如下图详细描述了OneNote电子笔记本的逻辑结构:

2、笔记本的创建、保存与共享

主要内容在文件下拉栏中,重点内容:

1)保存在云端

2)在本地备份

3)与他人共享

4)自动保存

3、笔记本的逻辑结构

1)分区组:类似于文件夹(分区组内可以继续创建分区)

2)页:分区组内创建页面(页面也可以拥有从属关系,即页面可以创建子页)

4、小结

5、参考链接

【OneNote教学】03第三课:笔记本的创建与逻辑结构_哔哩哔哩_bilibili

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值