leetcode_贪心算法

news2024/11/20 14:21:04

贪心算法相关题

  • 简单题目
    • 455.分发饼干
    • 1005.K次取反后最大化的数组和
    • 860.柠檬水找零
  • 序列问题
    • 376.摆动序列
      • 法一:贪心法
      • 法二:动态规划
    • 单调递增的数字
      • 简化版本
  • 有点难度
    • 53.最大子序和
      • 贪心算法
      • 动态规划
    • 134.加油站
    • 968.监控二叉树
  • 两个维度权衡问题
    • 分发糖果
    • 406.根据身高重建队列
  • 贪心解决股票问题
    • 122.买卖股票的最佳时机II
      • 贪心法
      • 动规法
  • 区间问题
    • 55.跳跃游戏
      • 贪心法
    • 45.跳跃游戏II
      • 动态规划
    • 452.用最少数量的箭引爆气球
    • 435.无重叠区间
    • 736.划分字母区间
    • 56.合并区间
      • 补充(改版自弓箭数量那题)
      • 贪心

简单题目

455.分发饼干

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        int count=0,i=0,j=0;
        while(i<g.size()&&j<s.size()){
            if(s[j]>=g[i]) {
                count++;
                i++;
            }
            j++;
        }
        return count;
    }
};

1005.K次取反后最大化的数组和

class Solution {
public:
    static bool cmp(int a,int b){
        return abs(a)>abs(b);
    }
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(),nums.end(),cmp);
        int sum=0;
        for(int i =0;i<nums.size();i++){
            if(nums[i]<0&&k>0){
                nums[i] = -nums[i];
                k--;
            }
        }
        if(k%2==1) nums[nums.size()-1]*=-1;
        for(int i =0;i<nums.size();i++){
            sum+=nums[i];
        }
        return sum;
    }
};

860.柠檬水找零

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        map<int,int> map1;
        for(int i =0;i<bills.size();i++){
            if(bills[i]==5)
                map1[5]++;
            if(bills[i]==10){
                map1[5]--;
                map1[10]++;
                if(map1[5]<0) return false;
            }
            if(bills[i]==20){
                if(map1[10]){
                    map1[5]--;
                    map1[10]--;
                }
                else{
                    map1[5]-=3;
                }
                map1[20]++;
                if(map1[5]<0||map1[10]<0) return false;
            }
        } 
        return true; 
    }
};

序列问题

376.摆动序列

法一:贪心法

局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值
整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。

我们根据正常理解,可以总结出我们需要统计波动的数量,定义prediff(nums[i]-nums[i-1])curdiff(nums[i+1]-nums[i]),则波动需要满足的条件是:(prediff<0&&curdiff>0) || (prediff>0&&curdiff<0)
但是这样会忽略平坡的情况,平坡分两种,

  1. 一是上下坡中有平坡,对于这种情况,我们只统计一个波动就好,默认统计prediff=0的情况,就是平坡在前,上下坡在后,统计这一波动,这对应的也是代码随想录中提到的删除平坡中左面的元素。
    在这里插入图片描述

  2. 二是单调坡中有平坡,这对应的是我们应该修改对于prediff的更新,因为单调坡中的拐点使用上面的条件确实会被统计两次。

在这里插入图片描述

最后考虑两个数以及数组两端的情况,默认最右面有一个峰值(res=1起步),两个数的话无法判断写死摆动序列为2.

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if(nums.size()==2) {
            if(nums[0]!=nums[1]) return nums.size();
            if(nums[0]==nums[1]) return 1;
        }
        int prediff=0,curdiff=0,res=1;
        for(int i =0;i<nums.size()-1;i++){
            curdiff=nums[i+1]-nums[i];
            if(prediff<=0&&curdiff>0||prediff>=0&&curdiff<0){
                res++;
                prediff=curdiff;
            }
        }
        return res;
    }
};

法二:动态规划

dp数组含义:

  • dp[i][0]:表示考虑前i个数,第i个数作为山峰的摆动子序列最长长度
  • dp[i][1]:表示考虑前i个数,第i个数作为山谷的摆动子序列最长长度

递推表达式:
dp[i][0] = max(dp[i][0],dp[j][1]+1) 其中0<j<i,其nums[j]<nums[i],表示将nums[i]接到某个山谷后面作为山峰的最长长度。
dp[i][1] = max(dp[i][1],dp[j][0]+1) 其中0<j<i,其nums[j]>nums[i],表示将nums[i]接到某个山峰后面作为山谷的最长长度

class Solution {
public:
    int dp[1010][2];
    int wiggleMaxLength(vector<int>& nums) {
        memset(dp,0,sizeof(dp));
        dp[0][0]=dp[0][1] = 1;
        for(int i =1;i<nums.size();i++)
        {
            dp[i][0] = dp[i][1] = 1;
            for(int j =0;j<i;j++)
                if(nums[i]>nums[j]) dp[i][0] = max(dp[i][0],dp[j][1]+1);
            for(int j=0;j<i;j++)
                if(nums[i]<nums[j]) dp[i][1] = max(dp[i][1],dp[j][0]+1);
        }
        return max(dp[nums.size()-1][0],dp[nums.size()-1][1]);
    }
};

单调递增的数字

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        if (n < 10) return n;
        string str = "";
        while (n) {
            char c = n % 10 + '0';
            str += c;
            n = n / 10;
        }
        reverse(str.begin(), str.end());
        for(int i =1;i<str.size();i++){
            if(str[i]<str[i-1]){
                str[i-1]-=1;
                for(int j=i;j<str.size();j++){
                    str[j]='9';
                }
                for(int k=i-2;k>=0;k--){
                    if(str[k]>str[k+1]){
                        str[k]-=1;
                        str[k+1]='9';
                    }
                }
            }
        }
        int num = 0;
        for (int i = 0; i < str.size(); i++) {
            num = num*10+str[i] - '0';
        }
        return num;
    }
};

简化版本

从后往前遍历,如果出现strNum[i - 1] > strNum[i]的情况,则strNum[i - 1]–,然后一直用一个flag记录i的位置,以便于之后将i之后所有卫生纸上的数字

class Solution {
public:
    int monotoneIncreasingDigits(int N) {
        string strNum = to_string(N);
        // flag用来标记赋值9从哪里开始
        // 设置为这个默认值,为了防止第二个for循环在flag没有被赋值的情况下执行
        int flag = strNum.size();
        for (int i = strNum.size() - 1; i > 0; i--) {
            if (strNum[i - 1] > strNum[i] ) {
                flag = i;
                strNum[i - 1]--;
            }
        }
        for (int i = flag; i < strNum.size(); i++) {
            strNum[i] = '9';
        }
        return stoi(strNum);
    }
};

有点难度

53.最大子序和

贪心算法

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int count=0,res=INT32_MIN;
        for(int i =0;i<nums.size();i++)
        {
           count+=nums[i];
           res = count>res?count:res;
           if(count<=0) count=0;
        }
        return res;
    }
};

动态规划

这道题写动规的时候,dp的含义直接设置成了前i个连续子数组的最大和,没有再设置res去保存最大值,导致dp[i]在更新的时候到底是最大值还是只是和的时候,出现了两层表示意义。比如1,2,3,-7,6,dp[3] = 6,但dp[3]按照原有含义,没有办法直接+nums[4]。

class Solution {
public:
    int dp[100010];
    int maxSubArray(vector<int>& nums) {
        memset(dp,0,sizeof(dp));
        int res = nums[0];
        dp[0] = nums[0];
        for(int i =1;i<nums.size();i++){
            dp[i] = max(dp[i-1]+nums[i],nums[i]);
            if(dp[i]>res) res=dp[i];
        }
        return res;
    }
};

134.加油站

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int min_gas = 0,sum_gas=0;
        for(int i =0;i<gas.size();i++){
            sum_gas=sum_gas+gas[i]-cost[i];
            if(sum_gas<min_gas) min_gas=sum_gas;
        }
        if(sum_gas<0) return -1;
        else{
            sum_gas=0;
            for(int i=gas.size()-1;i>=0;i--){
                sum_gas+=gas[i]-cost[i];
                if(sum_gas>=-min_gas){
                    return i;
                }
            }
        }
        return -1;
    }
};

968.监控二叉树

/**
 * 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:
    // 0:表示该节点没有被覆盖
    // 1:表示该节点有摄像头
    // 2:表示该节点被覆盖
    int ans;
    int traversal(TreeNode* cur){
        if(cur==nullptr) return 2;
        int left = traversal(cur->left);

        int right = traversal(cur->right);

        if(left==0||right==0) {
            ans++;
            return 1;
        }
        if(left==1||right==1){
            return 2;
        }
        if(left==2||right==2){
            return 0;
        }
        return -1;
    }
    int minCameraCover(TreeNode* root) {
        int root_num = traversal(root);
        if(root_num==0) ans++;
        return ans;

    }
};

两个维度权衡问题

分发糖果

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candy(ratings.size(),1);
        for(int i=1;i<ratings.size();i++){
            if(ratings[i]>ratings[i-1]){
                candy[i] = candy[i-1]+1;
            }
        }
        for(int i=ratings.size()-1;i>0;i--){
            if(ratings[i-1]>ratings[i]){
                candy[i-1]=max(candy[i]+1,candy[i-1]);
            }
        }
        int ans=0;
        for(int i =0;i<candy.size();i++){
            ans+=candy[i];
        }
        return ans;     
    }
};

406.根据身高重建队列

现根据身高从大到小排列,再根据k一个一个插入。

class Solution {
public:
    static bool cmp(vector<int>& a,vector<int>& b){
        if(a[0]==b[0]) return a[1]<b[1];
        else return a[0]>b[0];
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(),people.end(),cmp);
        vector<vector<int>> que;
        for(int i =0;i<people.size();i++){
            int position = people[i][1];
            que.insert(que.begin()+position,people[i]);
        }
        return que;
    }
};

贪心解决股票问题

122.买卖股票的最佳时机II

贪心法

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int sum=0;
        for(int i =1;i<prices.size();i++){
            if(prices[i]-prices[i-1]>0){
                sum+=prices[i]-prices[i-1];
            }
        }
        return sum;
    }
};

动规法

class Solution {
public:
    int dp[30010];
    int maxProfit(vector<int>& prices) {
        memset(dp,0,sizeof(dp));
        int sum=0;
        for(int i =1;i<prices.size();i++){
            dp[i]=dp[i-1] + max(prices[i]-prices[i-1],0);
        }
        return dp[prices.size()-1];
    }
};

区间问题

区间问题总结,除了两个跳跃游戏。我们一共左了四个区间的贪心算法题。用最少弓箭射爆气球,五重叠区间的个数,划分字母区间和合并区间。用最少的弓箭射爆气球,实际上我们要找的是重叠区间的个数,而射爆气球这道题认为[1,2],[2,3]不属于重叠区间,这需要注意。我们按照左边界排序后,只需要遍历interval中每一个右边界,每次更新重叠区间的右端点 r = min ( points [ i ] [ 1 ] , r ) r = \text {min}(\text{points}[i][1],r) r=min(points[i][1],r),然后处理每个interval左边界和r的关系就好。无重叠区间的个数实际上总区间个数减去重叠区间个数,所以看清楚条件[1,2],[2,3]属不属于重叠情况确立等号是否成立。划分字母区间这道题有点难度,需要统计每个字符出现的最远位置下标然后处理。合并区间,按左边界排序后,然后从左到右遍历看是否是重叠的,然后更新合并区间的左边界右边界。

55.跳跃游戏

贪心法

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int step=0;
        if(nums.size()==1) return true;
        for(int i =0;i<=step;i++){
            step=max(i+nums[i],step);
            if(step>=nums.size()-1) return true;
        }
        return false;
    }
};

45.跳跃游戏II

动态规划

class Solution {
public:
	//我的思路是:dp数组表示到第i个格子需要的最短次数
    //dp数组更新的递推公式是:从j=0个格子开始找
    int dp[10100];
    int jump(vector<int>& nums) {
        memset(dp, 10010, sizeof(dp));
        if (nums.size() == 1) return 0;
        else dp[0] = 0;
        for (int i = 1; i < nums.size(); i++) {
            for (int j = 0; j < i; j++) {
                if (j + nums[j] >= i) {
                    dp[i] = min(dp[j] + 1, dp[i]);
                    break;
                }
            }
        }
        return dp[nums.size() - 1];
    }
};

452.用最少数量的箭引爆气球

class Solution {
public:
    static bool cmp(vector<int>& a, vector<int>& b){
        if(a[0]==b[0]) return a[1]<b[1];
        else return a[0]<b[0];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        sort(points.begin(),points.end(),cmp);
        int l=points[0][0],r=points[0][1];
        int ans=1;
        for(int i =1;i<points.size();i++){
            l = points[i][0];
            r = min(points[i][1],r);
            if(l>r){
                r=points[i][1];
                ans++;
            }
        }
        return ans;
    }
};

435.无重叠区间

class Solution {
public:
    //无重叠区间的个数等于总区间个数减去重叠区间个数
    static bool cmp(vector<int>& a,vector<int>& b){
        if(a[1]==b[1]) return a[0]<b[0];
        else return a[1]<b[1];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        //这里需要记一下,按右边界排序要从左向右找
        //按左边界排序,要从右向左找
        sort(intervals.begin(),intervals.end(),cmp);
        int l=intervals[0][0],r=intervals[0][1];
        int ans=1;
        for(int i =1;i<intervals.size();i++){
            if(intervals[i][0]>=r){
                ans++;
                r=intervals[i][1];
            }
        }
        return intervals.size()-ans;
    }
};

736.划分字母区间

这道题不用回溯,不是所有的划分字母区间都要回溯,这道题主要在于统计之前遍历过所有字母的最远边界,如果当前下标到达了这个最远边界,说明到达了字符串的分割点。

class Solution {
public:
    //贪心法
    map<char,int> mp;
    vector<int> ans;
    vector<int> partitionLabels(string s) {
        for(int i =0;i<s.size();i++){
            mp[s[i]] = i;
        }
        int split=0,split1=-1;
        for(int i =0;i<s.size();i++){
            if(mp[s[i]]>split) split=mp[s[i]];
            if(i==split){
                ans.push_back(split-split1);
                split1= split;
            } 
        }
        return ans;
    }
};

56.合并区间

通过做这道题,我先是按照解上面题的常规套路,按照右边界排序,后来发现很多bug,这道合并区间的题如果从左到右遍历一定是先按左边界排列。

class Solution {
public:
    static bool cmp(vector<int>&a, vector<int>&b){
        if(a[0]==b[0]) return a[1]<b[1];
        else return a[0]<b[0];
    }
    vector<vector<int>> res;
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(),intervals.end(),cmp);
        int l = intervals[0][0];
        int r = intervals[0][1];
        for(int i =1;i<intervals.size();i++){
            if(intervals[i][0]<=r){
                r = max(intervals[i][1],r);
            }
            else{
                res.push_back({l,r});
                l = intervals[i][0];
                r = intervals[i][1];
            }
        }
        res.push_back({l,r});
        return res;
    }
};

补充(改版自弓箭数量那题)

class Solution {
public:
    //无重叠区间的个数等于总区间个数减去重叠区间个数
     static bool cmp(vector<int>& a, vector<int>& b){
        if(a[0]==b[0]) return a[1]<b[1];
        else return a[0]<b[0];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
       sort(intervals.begin(),intervals.end(),cmp);
        int l=intervals[0][0],r=intervals[0][1];
        int ans=1;
        for(int i =1;i<intervals.size();i++){
            l = intervals[i][0];
            r = min(intervals[i][1],r);
            if(l>=r){ //加个等号,认为等于的情况不属于交叉区间
                r=intervals[i][1];
                ans++;
            }
        }
        return intervals.size()-ans;
    }
};

贪心

要从覆盖范围出发,不管怎么跳,覆盖范围一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了重点得到的就是最小步数。

class Solution {
public:
 
    int jump(vector<int>& nums) {
        if(nums.size()==1) return 0;
        int curmaxindex = 0; // 当前覆盖最远距离下标,当前位置为i的话,能走到的最远距离就是i+nums[i]。
        int nextmaxindex = 0; // 记录走的最大步数
        int step = 0; // 下一步覆盖最远距离下标
        for(int i =0;i<=curmaxindex;i++){
            nextmaxindex = max(nums[i]+i,nextmaxindex); // 更新下一步能走到的最远距离
            if(i==curmaxindex){                         // 如果i已经走到了当前能走到的最大距离
                if(curmaxindex<nums.size()-1){
                    step++;                             // 那么我们一定要走下一步了,但下一步的落脚点在哪儿不用管
                    									// 不要误认为下一步落脚点一定是curdistance,这个没关系
                    curmaxindex=nextmaxindex;          // 更新当前覆盖最远距离下标
                    if(nextmaxindex>=nums.size()-1) break;  // 下一步的覆盖范围已经可以达到终点,结束循环
                }
            }
        }
        return step;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/388047.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB——系统环境

MATLAB概述MATLAB的发展MATLAB:MATrix LABoratory1980年前后&#xff0c;Cleve Moler教授编写的Linpack 和Eispack的接口程序。1984年&#xff0c;MATLAB第1版(DOS版)1992年&#xff0c;MATLAB4.0版1994年&#xff0c;MATLAB 4.2版1997年&#xff0c;MATLAB 5.0版1999年&#x…

12-Trie树

Trie树&#xff08;又称字典树、单词查找树&#xff09;是一种树型的数据结构&#xff0c;常用于保存和查找字符串&#xff0c;是一种十分高效率的存储和检索方式。 Trie树原理 我们先假设有六个字符串需要存储&#xff1a;abc、abcd、abef、cfgh、bc、bcd。Trie树的存储原理…

Scala04 方法与函数

Scala04 方法与函数 Scala 中的也有方法和函数的概念。 Scala中的 方法 是类的一部分。 Scala中的 函数 是一个对象&#xff0c;可以赋值给变量。 在类中定义的函数就是方法 4.1 方法 Scala 中方法 与 Java 中类似&#xff0c;是组成类的一部分 4.1.1 语法结构 格式&#x…

数据库“啃”不动?CnosDB带你轻松阅读十万行源码!

最近一直有社区的小伙伴问&#xff0c;我们很感兴趣CnosDB&#xff0c;但从何开始阅读CnosDB的代码呢&#xff0c;其实这个问题在之前的CnosDB HiTea直播时就有聊到&#xff0c;今天我们就再来回顾一下。CnosDB的源代码主要分为Query Engine和Storage Engine。Query Engine在qu…

JOSN数据转换和解析

文章目录JOSN数据转换和解析内容回顾Map 集合转成 JSON 字符串List 集合转换成 JSON 字符串Ajax 异步和同步异步概念同步概念异步和同步区别异步请求案例同步请求时间格式化旧时间 api 格式化格式化和解析的工具类JSTL 时间格式化JSTL 使用JOSN数据转换和解析 内容回顾 ajax …

指针的进阶续(笔试题强化练习)

写在前面&#xff1a;在上次我们学习了指针的相关类型的知识&#xff0c;对指针家族的成员基本有了了解&#xff0c;这次让我们跟着一些题目来练习和补充一些知识&#xff0c;这有助于我们强化理解这些知识。 话不多说&#xff0c;我们马上开始&#xff1a; 1.指针和数组的笔…

Vue基础学习 第一个Vue程序 el挂载点 v-指令(1)

Vue简介 Vue是一个Javascript框架Vue框架可以简化Dom操作响应式数据驱动 &#xff1a; 页面是由数据生成的&#xff0c;当数据出现改动&#xff0c;页面也会即时改变 第一个Vue程序 Vue中文文档官网&#xff1a;https://v2.cn.vuejs.org/v2/guide/ 根据官方文档的说法&#…

缓存与数据库的双写一致性

背景 在高并发的业务场景下&#xff0c;系统的性能瓶颈往往是出现在数据库上&#xff0c;用户并发访问过大&#xff0c;压力都打到数据库上。所以一般都会用redis做缓存层&#xff0c;起到一个缓冲作用&#xff0c;让请求先访问到缓存层&#xff0c;而不是直接去访问数据库&am…

Web3D发展趋势以及Web3D应用场景

1&#xff0c;Web3D发展趋势随着互联网的快速发展&#xff0c;Web3D技术也日渐成熟&#xff0c;未来发展趋势也值得关注。以下是Web3D未来发展趋势的七个方面&#xff1a;可视化和可交互性的增强&#xff1a;Web3D可以为三维数据提供可视化和可交互性的增强&#xff0c;将极大地…

CCNP350-401学习笔记(补充题目101-186)

101、 enable the https service 102、fabric edge node 103、 104、 105、 16113 106、filter access-group 10 107、 108、VETP 109、 110、 111、the server and the database can inititate communication 112、 113、 114、 115、 116、WAN edge&#xf…

【教程】去水印开源工具Lama Cleaner在Windows的安装和使用

一、Lama Cleaner是什么&#xff1f; Lama Cleaner是一款开源且免费的人工学习图片去水印程序&#xff08;个人主要学习用途&#xff09;&#xff0c;没有图片分辨率限制&#xff08;个人使用暂未发现&#xff09;&#xff0c;并且保存的图片质量很高&#xff08;个人觉得跟原…

MSTP多进程讲解与实验配置

目录 MSTP多进程 专业术语 MSTP多进程配置 在MSTP域配置 MSTP多进程 多进程的作用 将设备上的端口绑定到不同的进程中&#xff0c;以进程为单位进行MSTP计算&#xff0c;不在同一进程内的端口不参与此进程中的MSTP协议计算&#xff0c;实现各个进程之间的生成树计算相互独立…

【算法】DFS与BFS

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;题目的模拟很重要&#xff01;&#xff01;&#x1f43e; 文章目录1.区别2.DFS2.1 排列数字2.2 n-皇后问题3.BFS3.1走迷宫1.区别 搜索类型数据结构空间用途过程DFSstackO( n )不能用于最短路搜索到最深处&a…

leetcode打卡-深度优先遍历和广度优先遍历

200.岛屿数量 leetcode题目链接&#xff1a;https://leetcode.cn/problems/number-of-islands leetcode AC记录&#xff1a; 思路&#xff1a;深度优先遍历&#xff0c;从0&#xff0c;0开始遍历数组&#xff0c;使用boolean类型数组used记录是否被访问过&#xff0c;进行一…

28个案例问题分析---014课程推送页面逻辑整理--vue

一&#xff1a;背景介绍 项目开发过程中&#xff0c;前端出现以下几类问题&#xff1a; 代码结构混乱代码逻辑不清晰页面细节问题 二&#xff1a;问题分析 代码结构混乱问题 <template><top/><div style"position: absolute;top: 10px"><C…

SpringBoot监听机制-以及使用

11-SpringBoot事件监听 Java中的事件监听机制定义了以下几个角色&#xff1a; ①事件&#xff1a;Event&#xff0c;继承 java.util.EventObject 类的对象 ②事件源&#xff1a;Source &#xff0c;任意对象Object ③监听器&#xff1a;Listener&#xff0c;实现 java.util…

奇思妙想:超链接唤起本地应用

文章目录分析实现参考很多人的博客都有这样的小玩意&#xff0c;点击之后就可以直接与博主进行对话&#xff0c;而且无需添加好友。 先研究一下网页源代码&#xff1a; <a href"tencent://message/?uin88888888&Siteqq&Menuyes">联系我</a>很明…

Decoupled Knowledge Distillation(CVPR 2022)原理与代码解析

paper&#xff1a;Decoupled Knowledge Distillationcode&#xff1a;https://github.com/megvii-research/mdistiller/blob/master/mdistiller/distillers/DKD.py背景与基于响应logits-based的蒸馏方法相比&#xff0c;基于特征feature-based的蒸馏方法在各种任务上的表现更好…

【教学典型案例】14.课程推送页面整理-增加定时功能

目录一&#xff1a;背景介绍1、代码可读性差&#xff0c;结构混乱2、逻辑边界不清晰&#xff0c;封装意识缺乏![在这里插入图片描述](https://img-blog.csdnimg.cn/bbfc5f04902541db993944ced6b62793.png)3、展示效果不美观二&#xff1a;案例问题分析以及解决过程1、代码可读性…

现代操作系统——Linux架构与学习

小白的疑惑 在我决定从事嵌入式&#xff08;应用层&#xff09;方面的工作时&#xff0c;我查询了大量资料该如何学习&#xff0c;几乎所有观点不约而同的都指向了学习好Linux&#xff0c;大部分工作都是在Linux环境下来进行工作的。于是我雄心勃勃的去下载Linux&#xff0c;可…