前缀和算法——部分OJ题详解

news2024/12/23 13:42:59

(文章的题目解释可能存在一些问题,欢迎各位小伙伴私信或评论指点(双手合十))

关于前缀和算法

前缀和算法解决的是“快速得出一个连续区间的和”,以前求区间和的时间复杂度是O(N),使用前缀和可以直接降为O(1)

【模板】一维前缀和

【模板】前缀和_牛客题霸_牛客网 (nowcoder.com)

首先解释下题目:给我们一个长度为n的数组,但是我们要注意数组的下标是从1开始的,不是从0开始的,所以我们创建数组的时候要创建n+1大小的数组。 

然后是最重要的输入参数环节:一共要输入多组数据,分别如下:

  1. 第一组数为n和q,n表示要操作的数组长度,上面的示例中为3,q表示要对这个数组操作的次数,示例里为2,表示要进行两次操作,也就是要返回两个结果
  2. 第二组输入的数就是要进行操作的数组,长度为n
  3. 后面输入几组数据数量为第一组数据的q,示例中q为2,于是后面有两组数,假设q为3,后面就是三组数。后面的这几组数都是2个数组成,分别为l和r,表示left和right
  4. 然后就是操作部分,以示例为离,第三组数为1和2,所以就计算数组包含中1下标和2下标的区间内所有值的和,最后输出1+2=3;第四组数为2和3,计算数组中2和3下标区间的和,输出2+4=6。下面来分析下这道题:
  1. 首先是暴力解法:其实很简单,首先从指定下标开始,使用循环,循环次数为r-l,然后全部把数相加即可,就是一个简单的模拟。最差情况下,时间复杂度为O(N*q),绝对会超时,假设10个数,做10次从头加到尾的操作,就是10^10,绝对超时
  2. 使用前缀和算法,一般分为两步,第一步:预处理出来一个前缀和数组,用dp表示;第二步:使用前缀和数组。
  3. 其中dp里的元素排版是有讲究的,dp[i]表示[1, i]区间内所有元素的和,假设数组为[1, 2, 3, 4],那么dp数组就是[1, 3, 6, 10]。公式为dp[i] = dp[i - 1] + arr[i],(这个公式就是动态规划算法里的状态转移方程,以后讲),到这里,第一步“构建前缀和数组”步骤就完成了
  4. 然后就是步骤二“使用前缀和数组”,假设目标数组为[1, 2, 3, 4, 5, 6],要计算的区间为[3, 5],我们可以先算1到5区间的和,然后再减去1到2区间的和,最后就剩下3到5区间的和了。公式就是:

dp[R] - dp[L - 1]

问题:为什么下标要从1开始计数

解答: 在力扣上给我们的数组下标基本都是从1开始计数。就上面的公式:dp[R] - dp[L - 1]为例,假设计算[0, 2]区间的和,那么公式就是dp[2] - dp[-1]越界了,需要处理边界问题;但是下标从1开始的话就不用处理。

并且由于dp的构成,导致dp[0]这个位置没有数,我们直接设置为0即可,因为0加任何数都为0

#include <iostream>
#include<vector>
using namespace std;

int main() 
{
    //1,读入数据
    int n, q;
    cin >> n >> q;
    vector<int> arr(n + 1); //要n+1,因为下标从1开始
    for(int i = 1; i <= n; i++) cin >> arr[i]; //输入目标数组

    //2,构建前缀和数组
    vector<long long> dp(n + 1); //用long long防止溢出
    for(int i = 1; i <= n; i++) dp[i] = dp[i-1] + arr[i];

     //3,使用前缀和
     int l = 0, r = 0;
     while(q--)
     {
        cin >> l >> r;
        cout << dp[r] - dp[l - 1] << endl;;
     }
     return 0;
}

【模板】二维前缀和

【模板】二维前缀和_牛客题霸_牛客网 (nowcoder.com)

题目和第一题一样,只不过是把要操作的数组从一维变成了二维,后面的操作部分的一组数是4个数,前面两个数和后面两个数各自表示矩阵中的某个数的位置,求由这样两个数对角形成的正方形里所有数的和,其余操作一致,下面来分析下这道题:

  1.  首先是暴力解法:直接用两个for循环,直接一个一个算出正方形里的值,很简单。最差情况下,时间复杂度为O(m * n * q),肯定会超时,所以我们尝试用前缀和算法来解决
  2. 步骤一:预处理一个前缀和矩阵出来。前缀和矩阵我们还是命名为dp,长度和宽度也和原矩阵一样,然后就是dp里每个值表示的含义:d[i][j]表示从[1, 1]到[i, j]位置形成的这个正方形里,所有元素的和,如下图:
  3. 步骤二:使用前缀和矩阵,还是如下图:
  4. 最终,按照上面两个公式来解题,时间复杂度为O(m*n) + O(q)
#include <iostream>
#include<vector>
using namespace std;

int main()
{
    //1,读入数据
    int n = 0, m = 0, q = 0;
    cin >> n >> m >> q;
    vector<vector<int>> arr(n + 1, vector<int>(m + 1));
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin >> arr[i][j];

    //2,构建dp前缀和矩阵
    vector<vector<long long>> dp(n + 1, vector<long long>(m + 1));
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            dp[i][j] = dp[i-1][j] + dp[i][j-1] + arr[i][j] - dp[i-1][j-1]; //公式

    //3,使用dp前缀和矩阵
    while(q--)
    {
        int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
        cin >> x1 >> y1 >> x2 >> y2;
        cout << (dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1]) << endl;
    }
    return 0;
}

724.寻找数组的中心下标

724. 寻找数组的中心下标 - 力扣(LeetCode)

题目就不解释了哈,因为感觉我解释得可能还没原题好。下面来分析下这道题:

  1. 首先是暴力解法,也是大多数人第一时间想到的算法,假设数组下标为0~n,假设我要判断i这个下标是否是中心下标,要先算0 ~ (i-1)的和,再算(i+1) ~ n-1的和,然后比较两个值是否相等,然后枚举i下标,时间复杂度是O(N^2),肯定超时
  2. 我们可以利用前缀和来优化,下标i左边的和可以直接用前缀和[i-1]来表示,而下标i后面的和可以直接用后缀和[i-1]来表示
  3. 我们用 f 来表示前缀和数组 , g 来表示后缀和数组,其中f[i]表示[0, i-1]区间所有元素的和,g[i]表示[i+1, n-1]区间里所有元素的和
  4. f[i] = f[i-1] + nums[i-1], g[i] = g[i+1] + nums[i+1],构建前后缀和数组就用这两个公式
  5. 然后就是使用这个数组,也就是枚举所有的下标i,然后去判断两个位置是否相等,返回第一个相等时i的值,如果i到结尾了都没有,返回-1

细节问题:

  1. 初始化的时候,f[0]需要先赋值为0,不然会越界访问,同理g[n-1],在公式里就变成了g[n-1] = g[n] + nums[n],也越界访问了,所以g[n-1]也要赋值为0
  2. 然后是填表顺序,在填写f数组的时候是从左往右;但是填g数组的时候是从右往左
class Solution {
public:
    int pivotIndex(vector<int>& nums) {
        int n = nums.size();
        vector<int> f(n), g(n); //前缀和,后缀和数组
        
        //1,构建前缀和数组和后缀和数组
        for(int i = 1; i < n ; i++)
            f[i] = f[i - 1] + nums[i - 1];
        for(int i = n - 2; i >= 0; i--)
            g[i] = g[i + 1] + nums[i + 1];

        //2,使用前缀和数组
        for(int i = 0; i < n; i++) //枚举中心下标
        {
            if(f[i] == g[i]) return i;
        }
        return -1;
    }
};

238.除自身以外数组的乘积

238. 除自身以外数组的乘积 - 力扣(LeetCode)

解释下题目:给我们一个数组nums,让我们再构建一个数组answer返回,其中answer数组的answer[i]表示的含义是在nums中除nums[i]以外的其余各元素的和,相乘时题目保证不会溢出。下面来解释下这道题:

  1. 暴力解法也很简单,就枚举每一个位置,让后把其余值都相乘再记录,和前面题目的暴力解法一样,会超时哦,所以我们来尝试用前缀和来解决这道题:
  2. 这道题由于是求乘积,所以我们也可以叫做前缀积,所以需要对前面的前缀和模板大改一下,并且也要有后缀积
  3. 步骤一,预处理前缀积和后缀积:用 f 表前缀积, g 表示后缀积。首先f[i]只要表示[0, i-1]区间的积即可,所以f[i] = f[i-1] * nums[i-1];然后g[i]表示[i+1, n-1],所以g[i] = g[i+1] * nums[i+1]
  4. 步骤二,使用前缀数组:先构建ret目标数组,然后填这个数组就好了,非常简单,ret[i] = f[i] * g[i]

处理细节问题:

  • 和上面一样又不一样,f(0) = 1,g(n-1) = 1

class Solution 
{
public:
    vector<int> productExceptSelf(vector<int>& nums)
    {
        int n = nums.size();
        vector<int> f(n), g(n);
        f[0] = g[n-1] = 1;

        //1,构建前缀积和后缀积数组
        for(int i = 1; i < n; i++)
            f[i] = f[i-1] * nums[i-1];
        for(int i = n - 2; i >= 0; i--)
            g[i] = g[i+1] * nums[i+1];
        
        //2,使用
        vector<int> ret(n);
        for(int i = 0; i < n; i++)
            ret[i] = f[i] * g[i];
        
        return ret;
    }
};

560.和为K的子数组 

560. 和为 K 的子数组 - 力扣(LeetCode)

题目描述很简单,并且上面的示例很好懂,下面来解释下这道题:

  1.  首先是暴力解法:就是暴力枚举,因为只要涉及到“子数组”,暴力解法95%以上都是枚举所有子数组,然后一一判断,而且就算我们找到这个位置后也不能停止,因为数组元素是包含负数的,所以正负可能抵消掉,时间复杂度为O(N^2),超时
  2. 这道题不能用滑动窗口或双指针来优化,因为用滑动窗口做优化时,找到一种结果,一个区间后,left和right就移动了,但是假设我们以[-1, 1, 3, 2, -2]为例,假设滑动窗口找到了这个区间,但是我们可以发现,-1和1,2和-2是可以抵消的,所以就会出现在一个符合要求的区间内还有一个或多个符合要求的子区间,这样的情况滑动窗口是搞不了的(不能用双指针本质是因为包含负数
  3. 求区间和,可以用前缀和算法。暴力算法的本质就是,以某个位置为“起点”枚举的所有子数组,不关心结尾;我们可以反过来,以某一个位置为“结尾”枚举子数组,反过来向前枚举,不关心开头在哪。

细节问题:

  • 首先是前缀和假如哈希表的时机:先把所有前缀和全算出来,然后全扔哈希表里去。这个方法不行的,我们要算的是i位置之前的前缀和等于K的数量,全扔进去的话可能会统计到i位置之后的;所以在计算i位置之前,哈希表里只保存[0, i - 1]位置的前缀和
  • 我们其实不用创建一个前缀和数组:在计算dp[i]时,原先的公式是:dp[i] = dp[i-1] + nums[i],但是我们可以不创建前缀和数组,所以我们可以用以后个变量sum来标识dp[i-1],然后公式就可以写成dp[i] = sum + nums[i]; sum = dp[i],依次循环,就可以不创建前缀和数组从而求出前缀和
  • 如果整个前缀和等于K呢?假设一个区间[0, i]为K,所以按照前面的思路应该就算去[0, -1]这个区间去找和为0的区间,但是不存在-1区间,但是这也是一种情况,不能忽略。所以写代码时创建哈希表时,要先hash[0] = 1,避免“整个数组前缀和为K”这种情况被忽略
class Solution 
{
public:
    int subarraySum(vector<int>& nums, int k)
    {
        unordered_map<int, int> hash; //统计前缀和出现的次数
        hash[0] = 1;

        int sum = 0, ret = 0;
        for(auto x : nums)
        {
            sum += x; //计算当前位置的前缀和
            if(hash.count(sum - k)) ret += hash[sum - k]; //如果该前缀和符合要求,就统计该前缀和出现的次数
            hash[sum]++;
        }
        return ret;
    }
};

974.和可被K整除的子数组

974. 和可被 K 整除的子数组 - 力扣(LeetCode)

这道题是某一年蓝桥杯竞赛原题,先解释下题目:这道题描述和上面“和为K的子数组”很像,给一个整数数组nums和一个整数K,要求我们返回连续的子数组,该子数组的要求是,子数组元素的和可被K整除。下面来分析下这道题:

补充下知识:

  1. 同余定理:就算一个数学公式:(a - b) / p = k 余零,那么我们可以认为:a % p == b % p。举个例子:(26 - 12) / 7 = 2 余零,那么可以得出 (26 % 7) == (12 % 7) == 5。取余的本质其实就算让一个数不断的减另一个数,以7 % 2为例:7 % 2 = (7 - 2 -2 -2) = 1,所以我们也可以看作(1 + 2 * 3) % 2 = 1,所以我们就又可以得出一个公式:(a + p * k) % p = a%p
  2. C++, java 负数% 正数的结果以及修正:

下面来分析下这道题,解题思路和上面一道题很像

  1. 解法一就算暴力枚举:和上一道题非常相似,并且存在负数所以也不能用滑动窗口来优化,所以我们还是尝试用前缀和 + 哈希表来优化
class Solution 
{
public:
    int subarraysDivByK(vector<int>& nums, int k) 
    {
        unordered_map<int, int> hash; //统计前缀和出现的次数,第一个int为前缀和余数,第二个int表示次数
        hash[0] = 1; //0的余数只能是0,所以要单独处理一下

        int sum = 0, ret = 0;
        for(auto x : nums)
        {
            sum += x; //计算当前位置的前缀和
            int r = (sum % k + k) % k; //计算前缀和余数,修正后的余数
            if(hash.count(r)) ret += hash[r]; //如果该前缀和余数符合要求,就统计该前缀和余数出现的次数
            hash[r]++;
        }
        return ret;
    }
};

 525.连续数组

 525. 连续数组 - 力扣(LeetCode)

解释下题目:给一个二进制数组,这个数组只有0和1两种元素,找到含有相同数量的0和1的最长子数组,返回长度。题目很简单,下面来分析下这道题:

  1. 这道题如果用最普通的办法就是枚举子数组然后统计0和1的个数来比较,其实很不好搞,所以还是正难则反,我们可以先将所有的0改为“-1”,那么题目就可以变成找出最长的子数组使子数组中所有元素的和为0即可

处理细节:

  1. 哈希表里存什么?在这道题里,我们不关心前缀和有多少个,我们只关心你的长度,所以<int, int>,第一个int还是前缀和不变,第二个int不存个数了,存的应该是下标
  2. 什么时候存入哈希表?在sum和下标i使用完成之后再扔哈希表里去
  3. 如果出现重复的<sum, i>,如何存?当 i = 9时,sum符合要求,但是假设当j = 4时,sum也符合要求,这时,我们应该选择更靠前的下标,因为下标越靠前,算出来的子数组越长哦,所以要存<sum, j>
  4. 默认的前缀和的和为0的情况,如何存?当整个数组的sum为0时,我们是要在nums[-1]这个位置寻找前缀和为0的数组的,因此在上一道题里面我们是hash[0] = 1,表示默认有一个前缀和为0的,表示前缀和为0的数组有一个,上面那一道题村的是个数,这道题我们要存的是下标,所以这道题我们要hash[0] = -1
  5. 长度怎么算?
class Solution 
{
public:
    int findMaxLength(vector<int>& nums) 
    {
        unordered_map<int, int> hash; //细节1
        hash[0] = -1; //细节4

        int sum = 0, ret = 0;
        for(int i = 0; i < nums.size(); i++)
        {
           if(nums[i] == 0) sum += -1; //将0变成-1
           else sum += 1;
           if(hash.count(sum)) ret = max(ret, i - hash[sum]); //细节3,推导长的那一个数组的长度
           else hash[sum] = i; //如果存在相同的sum,就更新长的那一个数组,如果是新的sum,就扔哈希表里去
        }
        return ret;
    }
};

1314.矩阵区域和

1314. 矩阵区域和 - 力扣(LeetCode)

前面的都是一维前缀和题目,是时候做一下二维前缀和了。题目如下图: 下面来解释下这道题:

  1. 这道题明显就算要求我们快速求出矩阵中某一个区间的和,所以就要用到我们的“二维前缀和算法”,关于二维前缀和可以再划到前面第二题去复习一下。初始化前缀和矩阵的公式为:dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + mat[i][j];使用公式为:假设我们要求的最终结果为ret = dp[x2][y2] = dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1]
  2. 回到本题,我们要计算answer[i][j]的值,我们首先要知道[i][j]对应得mat矩阵中选中得子矩阵的左上角左边和右下角坐标,这个其实很好找,根据延申规则来即可,公式为:左上角坐标 = [i - k][j - k];右下角坐标 = [i + k][j + k],由于计算后得坐标可能会越界,如下图:
  3. 还有一个重要的关系,就是下标的映射关系:在第一和第二题中,牛客提供给我们的数组和下标都是从1开始的,规避了边界情况,但是力扣给我们的都是从0开始的;简单来说,假设我们的dp矩阵要填的位置是(x, y),那么这个位置的值我们需要从原矩阵mat的(x-1, y-1)去找的,原数组下标从1开始的话没问题,因为第0行和第0列的值默认为1,构建dp时正常的;但是当原矩阵下标从0开始,由于0-1 = -1,所以就会有非常非常非常多的边界情况需要处理,代码写起来会又难又长。所以我们前面的初始化dp[i][j]的公式就要稍微修改下:dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + mat[i - 1][j - 1]
  4. 然后在使用的时候,还有一个地方需要注意:answer矩阵也是从0开始计数的,当填充answer[x][y]这个位置的值时,要去dp矩阵中找数,那么找的应该就是dp[x + 1][y + 1],但是对应到上面的ret公式里的话,就要全部加1,太麻烦,所以我们可以直接在求坐标的时候就+1,如下图:
class Solution 
{
public:
    vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) 
    {
        int m = mat.size(), n = mat[0].size(); //计算原矩阵的长和宽大小
        
        //1,构建前缀和dp矩阵
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        for(int i = 1; i <= m; i++)
            for(int j = 1; j <= n; j++)
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + mat[i - 1][j - 1];

        //2,使用前缀和矩阵
        vector<vector<int>> ret(m, vector<int>(n));
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
            {
                int x1 = max(0, i - k) + 1, y1 = max(0, j - k) + 1;
                int x2 = min(m - 1, i + k) + 1, y2 = min(n - 1, j + k) + 1;
                ret[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];
            }
        return ret;
    }
};

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

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

相关文章

关于springboot的@DS(““)多数据源的注解无法生效的原因

对于com.baomidou.dynamic.datasource.annotation的DS注解&#xff0c;但凡有一个AOP的修改都会影响到多数据源无法生效的问题&#xff0c;本次我是添加了方法上添加了Transactional&#xff0c;例如下图&#xff1a; 在方法上写了这个注解&#xff0c;会影响到DS("db2&qu…

MODEL4高性价比工业级HMI芯片在喷码机解决方案中的应用

一、概述 随着工业自动化与智能化的发展&#xff0c;喷码机作为标识设备在各行各业中扮演着至关重要的角色。为满足市场对于高效、精准、灵活喷码的需求&#xff0c;我们推出了基于MODEL4工业级HMI芯片的喷码机解决方案。 该方案集成了高性能国产嵌入式64位RISC-V内核芯片组&…

<数据集>铁轨缺陷检测数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;844张 标注数量(xml文件个数)&#xff1a;844 标注数量(txt文件个数)&#xff1a;844 标注类别数&#xff1a;3 标注类别名称&#xff1a;[Spalling, Squat, Wheel Burn] 序号类别名称图片数框数1Spalling3315522…

集线器、交换机、路由器的区别,冲突域、广播域

冲突域 定义&#xff1a;同一时间内只能有一台设备发送信息的范围。 分层&#xff1a;基于OSI模型的第一层物理层。 广播域 定义&#xff1a;如果某个站点发出一个广播信号&#xff0c;所有能接受到这个信号的设备的范围称为一个广播域。 分层&#xff1a;基于OSI模型的第二…

绿色水利,智慧未来:数字孪生技术在智慧水库建设中的应用,助力实现水资源的可持续利用与环境保护的双赢

本文关键词&#xff1a;智慧水利、智慧水利工程、智慧水利发展前景、智慧水利技术、智慧水利信息化系统、智慧水利解决方案、数字水利和智慧水利、数字水利工程、数字水利建设、数字水利概念、人水和协、智慧水库、智慧水库管理平台、智慧水库建设方案、智慧水库解决方案、智慧…

【Python】open()函数的全面解析:如何读取和写入文件

文章目录 1. 基本用法&#xff1a;打开文件2. 不同模式的使用3. 文件读取方法3.1 readline()方法3.2 readlines()方法 4. 上下文管理器5. 错误处理6. 小结 在编程过程中&#xff0c;文件操作是一个非常常见的任务&#xff0c;而Python的open()函数是进行文件操作的基础。通过op…

Sparse4D-v3:稀疏感知的性能优化及端到端拓展

极致的感知性能与极简的感知pipeline一直是牵引我们持续向前的目标。为了实现该目标&#xff0c;打造一个性能优异的端到端感知模型是重中之重&#xff0c;充分发挥深度神经网络数据闭环的作用&#xff0c;才能打破当前感知系统的性能上限&#xff0c;解决更多的corner case&am…

分布式 I/O 系统Modbus TCP 耦合器BL200

BL200 耦合器是一个数据采集和控制系统&#xff0c;基于强大的 32 位微处理器设计&#xff0c;采用 Linux 操作系统&#xff0c;可以快速接入现场 PLC、SCADA 以及 ERP 系统&#xff0c; 内置逻辑控制、边缘计算应用&#xff0c;支持标准 Modbus TCP 服务器通讯&#xff0c;以太…

Ubuntu Desktop Docker 配置代理

Ubuntu Desktop Docker 配置代理 主要解决 docker pull 拉取不了镜像问题. Docker Desktop 配置代理 这个比较简单, 直接在 Docker Desktop 里设置 Proxies, 示例如下: http://127.0.0.1:7890 Docker Engine 配置代理 1.Docker Engine 使用下面配置文件即可, root 用户可…

Java面试八股之简述单例redis并发承载能力

简述单例redis并发承载能力 单例Redis实例的并发承载上限受到多种因素的影响&#xff0c;包括但不限于硬件性能、网络条件、数据集大小、操作类型以及Redis自身的配置。以下是几个关键因素的详细说明&#xff1a; 硬件性能&#xff1a; CPU&#xff1a;Redis主要依赖于CPU的…

服务器基础1

服务器基础复习01 1.环境部署 系统&#xff1a;华为欧拉系统 网络简单配置nmtui 因为华为欧拉系统密码需要复杂度 所以我们可以进入后更改密码 echo 123 | passwd --stdin root也可以 echo "root:123" | chpasswd2.关闭防火墙&#xff0c;禁用SElinux 首先先关…

BlueToothLE 拓展中writeBytesWithResponse与writeBytes有什么区别?

writeBytesWithResponse与writeBytes有什么区别&#xff1f; 根据文档&#xff0c;有WithRespon的&#xff0c;会触发一个 BytesWritten 事件&#xff0c;另一个不触发这个事件&#xff1a;App Inventor 2 低功耗蓝牙 BlueToothLE 拓展 App Inventor 2 中文网

SQl server 练习3

课后作业 在homework库下执行&#xff1a; CREATE TABLE user_profile_2 ( id int NOT NULL, device_id int NOT NULL, gender varchar(14) NOT NULL, age int , university varchar(32) NOT NULL, gpa float, active_days_within_30 float, question_cnt float, answer_cnt fl…

昇思25天学习打卡营第14天|DCGAN 与漫画头像生成:原理剖析与训练实战

目录 数据集下载 数据处理 构建生成器 构建判别器 模型训练 结果展示 数据集下载 首先尝试卸载已安装的 mindspore 库&#xff0c;然后通过指定的镜像源安装特定版本&#xff08;2.2.14&#xff09;的 mindspore 库。从指定的 URL 下载一个 zip 文件到当前目录下的 ./faces…

kubernetes k8s Deployment 控制器配置管理 k8s 红蓝部署 金丝雀发布

目录 1、Deployment控制器&#xff1a;概念、原理解读 1.1 Deployment概述 1.2 Deployment工作原理&#xff1a;如何管理rs和Pod&#xff1f; 2、Deployment资源清单文件编写技巧 3、Deployment使用案例&#xff1a;创建一个web站点 4、Deployment管理pod&#xff1a;扩…

信创学习笔记(三),信创之操作系统OS思维导图

创作不易 只因热爱!! 热衷分享&#xff0c;一起成长! “你的鼓励就是我努力付出的动力” 一. 回顾信创CPU芯片 1. x86应用生态最丰富, 海光(3,5,7)授权较新,无桌面授权,多用于服务器 兆芯(ZX, KX, KH)授权较早期. 2. ARMv8移动端应用生态丰富, 华为鲲鹏(9) ,制裁中&#xff0c;…

JWT令牌详细解析

JWT令牌 前言一、JWT是什么&#xff1f;二、JWT与传统CookieSession的对比三、JWT1. JWT的功能2. JWT的结构3. JWT的使用 前言 主要介绍了SpringBoot集成JWT令牌详细说明,JWT方式校验方式更加简单便捷化&#xff0c;无需通过redis缓存&#xff0c;而是直接根据token取出保存的…

前端报错adding CSS “touch-action: none“ to this element解决方案

目录 如图所示控制台出现报错&#xff1a; 原因&#xff1a; touch-action 介绍&#xff1a; 解决方案&#xff1a; 1.手动设置touch-action&#xff1a; 2.使用条件渲染&#xff1a; 3.CSS样式隔离&#xff1a; 4.浏览器兼容性&#xff1a; 5. 忽略警告 如图所示控制台…

持续集成04--Jenkins结合Gitee创建项目

前言 在持续集成/持续部署&#xff08;CI/CD&#xff09;的旅途中&#xff0c;Jenkins与版本控制系统的紧密集成是不可或缺的一环。本篇“持续集成03--Jenkins结合Gitee创建项目”将引导如何将Jenkins与Gitee&#xff08;一个流行的Git代码托管平台&#xff09;相结合&#xff…

华为USG6000V防火墙安全策略用户认证

目录 一、实验拓扑图 二、要求 三、IP地址规划 四、实验配置 1&#x1f923;防火墙FW1web服务配置 2.网络配置 要求1&#xff1a;DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 要求2&#xff1a;生产区不…