代码随想录-Day44

322. 零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例 2:

输入:coins = [2], amount = 3
输出:-1
示例 3:

输入:coins = [1], amount = 0
输出:0
在这里插入图片描述

class Solution {
    public int coinChange(int[] coins, int amount) {
        int max = Integer.MAX_VALUE;
        int[] dp = new int[amount + 1];
        //初始化dp数组为最大值
        for (int j = 0; j < dp.length; j++) {
            dp[j] = max;
        }
        //当金额为0时需要的硬币数目为0
        dp[0] = 0;
        for (int i = 0; i < coins.length; i++) {
            //正序遍历:完全背包每个硬币可以选择多次
            for (int j = coins[i]; j <= amount; j++) {
                //只有dp[j-coins[i]]不是初始最大值时,该位才有选择的必要
                if (dp[j - coins[i]] != max) {
                    //选择硬币数目最小的情况
                    dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
                }
            }
        }
        return dp[amount] == max ? -1 : dp[amount];
    }
}

这段Java代码实现了一个经典的动态规划问题——“完全背包问题”的一个应用场景:给定不同面额的硬币coins和一个总金额amount,计算最少需要多少个硬币凑出这个金额,如果不可能凑出则返回-1。这里是使用完全背包的思路,即每种硬币可以无限使用。

代码解析:

  1. 初始化:首先,定义一个dp数组,长度为amount + 1,并将其所有值初始化为Integer.MAX_VALUE,表示在没有计算之前,达到每个金额所需的最小硬币数为正无穷大。例外的是,dp[0]初始化为0,因为当金额为0时,不需要任何硬币。

  2. 双重循环

    • 外层循环遍历硬币数组coins,即遍历每一种硬币面额。
    • 内层循环从当前硬币的面额coins[i]开始遍历到总金额amount。这是因为在遍历到的金额j上,只有当j至少为当前硬币面额时,才有可能使用当前硬币去构成这个金额。
  3. 状态转移方程:对于内层循环中的每个j,如果dp[j - coins[i]]不是初始的最大值(即存在一种方式可以构成j - coins[i]的金额),则考虑使用一个面额为coins[i]的硬币,更新dp[j]dp[j]dp[j - coins[i]] + 1中的较小值。这里dp[j - coins[i]] + 1表示在构成j - coins[i]的基础上再加一个面额为coins[i]的硬币。

  4. 返回结果:最后,检查dp[amount]是否仍为Integer.MAX_VALUE,如果是,则说明没有找到任何组合可以凑成总金额,返回-1;否则返回dp[amount],即最少需要的硬币数。

总结:

这段代码通过动态规划的完全背包方法,有效解决了最少硬币数量问题,时间复杂度为O(coins.length * amount),空间复杂度为O(amount)。

279. 完全平方数

给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

示例 1:

输入:n = 12
输出:3
解释:12 = 4 + 4 + 4
示例 2:

输入:n = 13
输出:2
解释:13 = 4 + 9
在这里插入图片描述

方法一:

class Solution {
    // 版本一,先遍历物品, 再遍历背包
    public int numSquares(int n) {
        int max = Integer.MAX_VALUE;
        int[] dp = new int[n + 1];
        //初始化
        for (int j = 0; j <= n; j++) {
            dp[j] = max;
        }
	//如果不想要寫for-loop填充數組的話,也可以用JAVA內建的Arrays.fill()函數。
	//Arrays.fill(dp, Integer.MAX_VALUE);
	
        //当和为0时,组合的个数为0
        dp[0] = 0;
        // 遍历物品
        for (int i = 1; i * i <= n; i++) {
            // 遍历背包
            for (int j = i * i; j <= n; j++) {
                //if (dp[j - i * i] != max) {
                    dp[j] = Math.min(dp[j], dp[j - i * i] + 1);
                //}
		//不需要這個if statement,因爲在完全平方數這一題不會有"湊不成"的狀況發生( 一定可以用"1"來組成任何一個n),故comment掉這個if statement。
            }
        }
        return dp[n];
    }
}

这段Java代码是解决完全平方数问题的一个动态规划实现,目标是找出最少数量的完全平方数(例如1, 4, 9, 16…)之和,使其等于给定的正整数n。代码采用了“先遍历物品,再遍历背包”的动态规划策略,这里的“物品”指的是完全平方数,而“背包”则是我们需要达到的目标和n

代码解析

  1. 初始化dp数组:首先,创建一个长度为n+1的数组dp,其中dp[j]表示和为j时所需的最少完全平方数的个数。初始化所有dp[j]Integer.MAX_VALUE,表示初始时没有找到任何组合。但因为任何正整数都可以由无数个1^2组成,所以实际上不需要初始化为Integer.MAX_VALUE,直接初始化为一个较大的数即可,或明确知道最小组合数为1(当j > 0时)。注释中提到的Arrays.fill(dp, Integer.MAX_VALUE);是一种更简洁的初始化方式,但在这个特定问题上下文里,初始化为极大值然后在特定条件下更新的逻辑是多余的。

  2. 初始化dp[0]:当和为0时,不需要任何完全平方数,所以dp[0]设置为0。

  3. 双重循环

    • 外层循环遍历所有可能的完全平方数(由1^2√n的平方),用i表示当前考虑的完全平方数的根。
    • 内层循环遍历从当前完全平方数i*i开始到目标和n的所有可能和j。对于每个j,如果可以通过添加当前完全平方数i*i使得总和不超过n,并且这样的操作能减少之前记录的最少完全平方数的个数,就更新dp[j]的值为dp[j - i * i] + 1
  4. 返回结果:最后返回dp[n],即和为n时所需的最少完全平方数的个数。

注意

  • 代码注释中指出的“不需要这个if statement”,是因为在找完全平方数之和的问题中,任何正整数n都可以通过至少一个1^2(即至少一个1)来组合得到,所以直接尝试更新dp[j]的值而不需检查之前是否达到过是不可能的状态(即dp[j - i * i] != max的检查没有必要)。

综上,这段代码通过动态规划方法有效地求解了最少完全平方数之和的问题。

方法二:

class Solution {
    // 版本二, 先遍历背包, 再遍历物品
    public int numSquares(int n) {
        int max = Integer.MAX_VALUE;
        int[] dp = new int[n + 1];
        // 初始化
        for (int j = 0; j <= n; j++) {
            dp[j] = max;
        }
        // 当和为0时,组合的个数为0
        dp[0] = 0;
        // 遍历背包
        for (int j = 1; j <= n; j++) {
            // 遍历物品
            for (int i = 1; i * i <= j; i++) {
                dp[j] = Math.min(dp[j], dp[j - i * i] + 1);
            }
        }
        return dp[n];
    }
}

这段Java代码是解决“完全平方数”的另一个动态规划实现版本,目标依然是找出最少数量的完全平方数(如1, 4, 9, 16…)之和,使得这个和等于给定的正整数n。与第一个版本的主要区别在于遍历的顺序:这里是“先遍历背包,再遍历物品”。

代码解析

  1. 初始化:与第一个版本相同,首先创建一个长度为n+1的数组dp,其中dp[j]表示和为j时所需的最少完全平方数的个数。初始化所有dp[j]Integer.MAX_VALUE,然后设置dp[0]=0,表示和为0时不需要任何完全平方数。

  2. 遍历顺序改变

    • 外层循环现在遍历背包容量(从1到n),用j表示当前考虑的总和。
    • 内层循环遍历所有可能的完全平方数(从1^2到刚好不超过当前总和j的完全平方数),用i表示当前完全平方数的根。这确保了每次内循环都是对一个有效的完全平方数进行操作,不会超出背包容量。
  3. 状态转移:对于每个背包容量j,遍历所有小于等于它的完全平方数i*i,并尝试将当前完全平方数加入组合中(即从dp[j - i * i]转移而来),然后通过Math.min()函数更新dp[j]为已知的最小组合数。

  4. 返回结果:最后返回dp[n],即和为n时,所需最少的完全平方数个数。

优缺点

  • 优点:这种“先遍历背包,再遍历物品”的方式直接反映了背包问题的经典解法,逻辑上清晰地表达了对于每个总和j,尝试用所有可能的完全平方数去填充它,寻找最小组合数。
  • 缺点:在这个特定问题上,两种遍历顺序(先物品后背包 vs. 先背包后物品)在逻辑复杂度和效率上并无本质区别,主要取决于个人理解偏好。实际上,由于完全平方数的特殊性(连续的完全平方数之间差距增大),遍历顺序对性能的影响相对较小。

总之,这个版本提供了解决“完全平方数”问题的另一种动态规划实现思路,关键在于遍历顺序的调整,但核心的动态规划思想和状态转移方程保持一致。

139. 单词拆分

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:

输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以由 “leet” 和 “code” 拼接成。
示例 2:

输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以由 “apple” “pen” “apple” 拼接成。
注意,你可以重复使用字典中的单词。
示例 3:

输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false
在这里插入图片描述

方法一:

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        HashSet<String> set = new HashSet<>(wordDict);
        boolean[] valid = new boolean[s.length() + 1];
        valid[0] = true;

        for (int i = 1; i <= s.length(); i++) {
            for (int j = 0; j < i && !valid[i]; j++) {
                if (set.contains(s.substring(j, i)) && valid[j]) {
                    valid[i] = true;
                }
            }
        }

        return valid[s.length()];
    }
}

这段Java代码是一个解决方案,用于解决“单词拆分”问题。给定一个字符串s和一个字典wordDict(单词列表),判断字符串s是否可以被空格拆分成一个或多个字典中的单词。这是一个典型的动态规划问题。

代码解析

  1. 数据结构转换:首先,将wordDict转换为哈希集合HashSet<String> set,这样可以以O(1)的时间复杂度查询一个字符串是否在字典中。

  2. 初始化:定义一个布尔型数组valid,长度为s.length() + 1,其中valid[i]表示字符串s的前i个字符组成的子串是否可以被拆分成字典中的单词。初始化valid[0]true,因为空字符串是可以“拆分”的。

  3. 动态规划填充:外层循环从1遍历到s.length(),代表当前正在检查的子串的结束位置。内层循环从0遍历到当前的结束位置i,这是为了找到所有可能的前缀子串。如果存在某个前缀子串(从索引ji)在字典集合中,并且这个前缀子串的前一个位置(即j)的子串也是合法的(valid[j]true),那么将当前位置i标记为合法(valid[i] = true)。这里使用了!valid[i]作为提前终止的条件,一旦找到一个合法的拆分方式就不再继续查找,提高了效率。

  4. 返回结果:最后返回valid[s.length()],即整个字符串s是否可以被成功拆分。

示例

假设s = "leetcode"wordDict = ["leet", "code"],该函数将返回true,因为可以将s拆分成"leet"和"code",这两个单词都在字典中。

这段代码通过动态规划有效地解决了单词拆分问题,具有较好的时间和空间效率。

方法二:

// 另一种思路的背包算法
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        boolean[] dp = new boolean[s.length() + 1];
        dp[0] = true;

        for (int i = 1; i <= s.length(); i++) {
            for (String word : wordDict) {
                int len = word.length();
                if (i >= len && dp[i - len] && word.equals(s.substring(i - len, i))) {
                    dp[i] = true;
                    break;
                }
            }
        }

        return dp[s.length()];
    }
}

这段代码同样采用动态规划的思路来解决“单词拆分”问题,但实现方式稍有不同,具体解析如下:

算法思路

  • 初始化:创建一个布尔型数组dp,长度为s.length() + 1,其中dp[i]表示字符串s的前i个字符组成的子串是否能被字典中的单词组合覆盖。初始化dp[0] = true,表示空字符串是可以被任何词典中的单词组合覆盖的。

  • 双重循环遍历

    • 外层循环从1遍历到s.length(),用i表示当前考虑的子串的结束位置。
    • 内层循环遍历字典wordDict中的每个单词word
      • 计算当前单词的长度len
      • 判断当前子串的起始位置是否允许截取长度为len的子串,即i >= len,同时检查前len个字符组成的子串(即s.substring(i - len, i))是否与当前单词相等,并且这个子串的前一个位置的子串是否能被词典中的单词组合覆盖(即dp[i - len]true)。
      • 如果上述条件满足,说明找到了一个匹配的单词,可以将当前位置i标记为true并跳出内层循环,因为一旦找到一个合法的拆分方式就没有必要继续检查当前i的其他单词了(利用了“一旦满足条件即可结束”的剪枝优化)。
  • 返回结果:最后返回dp[s.length()],表示整个字符串s是否可以被字典中的单词组合覆盖。

优势与特点

  • 剪枝优化:通过在找到符合条件的单词后立即中断内层循环,减少了不必要的循环次数,提高了算法效率。
  • 直观易懂:代码直接体现了对每个子串尝试匹配字典中单词的过程,逻辑较为直观。
  • 空间效率:此方法仅使用了一个长度等于字符串长度加一的布尔数组,空间复杂度为O(n),其中n为字符串s的长度,与题目给定的字典大小无关,较为高效。

综上所述,这是一种有效且易于理解的动态规划解法,适用于解决给定字符串是否能被字典中的单词拆分的问题。

方法三:

// 回溯法+记忆化
class Solution {
    private Set<String> set;
    private int[] memo;
    public boolean wordBreak(String s, List<String> wordDict) {
        memo = new int[s.length()];
        set = new HashSet<>(wordDict);
        return backtracking(s, 0);
    }

    public boolean backtracking(String s, int startIndex) {
        // System.out.println(startIndex);
        if (startIndex == s.length()) {
            return true;
        }
        if (memo[startIndex] == -1) {
            return false;
        }

        for (int i = startIndex; i < s.length(); i++) {
            String sub = s.substring(startIndex, i + 1);
	    // 拆分出来的单词无法匹配
            if (!set.contains(sub)) {
                continue;                
            }
            boolean res = backtracking(s, i + 1);
            if (res) return true;
        }
        // 这里是关键,找遍了startIndex~s.length()也没能完全匹配,标记从startIndex开始不能找到
        memo[startIndex] = -1;
        return false;
    }
}

这段代码提供了一个使用回溯法加记忆化的解决方案来解决“单词拆分”问题。给定一个字符串s和一个单词字典wordDict,判断字符串s是否可以被空格拆分成一个或多个字典中的单词。以下是代码的详细解析:

类成员变量

  • set: 存储字典wordDict中的所有单词,使用HashSet以支持快速查找。
  • memo: 记忆化数组,用于存储字符串s的各个起始位置是否能够被拆分成字典中的单词。初始化为整型数组,长度与s相同,初始值默认为0,-1表示从该位置开始的子串不能被拆分。

方法解析

wordBreak 方法
  1. 初始化memo数组和set集合。
  2. 调用backtracking方法,从字符串的起始位置开始尝试拆分。
backtracking 方法
  • 参数:

    • s: 输入字符串。
    • startIndex: 当前开始拆分的位置索引。
  • 目的:

    • 递归地尝试从startIndex开始的子串是否能被拆分成字典中的单词。
  • 逻辑:

    • 基础情况:如果startIndex等于字符串长度,说明已经成功拆分到末尾,返回true
    • 记忆化检查:如果memo[startIndex]为-1,说明从startIndex开始的子串已经被探索过且不可拆分,直接返回false
    • 遍历:从startIndex到字符串结尾,逐步尝试截取子串,并检查该子串是否在字典中。
      • 如果子串在字典中,递归调用backtracking(s, i + 1),尝试剩余部分能否拆分。
      • 如果剩余部分可以被拆分,则当前子串也能被拆分,返回true
    • 回溯:如果所有尝试都无法成功拆分,标记memo[startIndex] = -1,表示从这个位置开始的子串不能被拆分,然后返回false

关键点

  • 记忆化搜索:通过memo数组避免重复计算,提高效率。
  • 回溯:在尝试失败后记录失败信息,防止同一子问题的重复探索。

这种方法在处理较长字符串和较大字典时,相较于简单的递归或暴力搜索能显著提升效率,但消耗的空间也会相应增加,主要是由于记忆化数组的使用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ARCGIS python 裁剪栅格函数 arcpy.management.Clip

ARCGIS python 裁剪栅格函数 arcpy.management.Clip 1 功能 裁剪掉栅格数据集、镶嵌数据集或图像服务图层的一部分。 2 使用情况 基于模板范围提取部分栅格数据集&#xff0c;输出与模板范围相交的所有像素使用以 x 和 y 坐标的最小值和最大值确定的包络矩形或使用输出范围文…

商汤上海AI实验室联合发布:自动驾驶全栈式高精度标定工具箱(含车、IMU、相机、激光雷达等的标定)

前言 在自动驾驶技术飞速发展的今天&#xff0c;传感器的精确标定对于确保系统性能至关重要。SensorsCalibration&#xff0c;一个专为自动驾驶车辆设计的标定工具箱&#xff0c;提供了一套全面的解决方案&#xff0c;用于校准包括IMU、激光雷达、摄像头和雷达在内的多种传感器…

Evented PLEG: iSulad 稳态 CPU 利用率降低30%的关键特性

背景 容器技术在不断发展的过程中&#xff0c;已被广泛应用于多种场景。OpenAtom openEuler&#xff08;简称"openEuler"&#xff09; 社区容器引擎项目 iSulad[1]面向 CT、IT 领域的不同需求而生&#xff0c;它具有轻量级、高性能的特点&#xff0c;可以在资源受限…

vue3引入本地静态资源图片

一、单张图片引入 import imgXX from /assets/images/xx.png二、多张图片引入 说明&#xff1a;import.meta.url 是一个 ESM 的原生功能&#xff0c;会暴露当前模块的 URL。将它与原生的 URL 构造器 组合使用 注意&#xff1a;填写自己项目图片存放的路径 /** vite的特殊性…

技术干货丨基于MotionView的虚拟路面疲劳分析

虚拟路面VPG&#xff08;Virtual Proving Ground&#xff09;现在正被广泛应用于汽车的疲劳耐久分析中&#xff0c;相较于传统的道路载荷谱数据采集的疲劳计算方法&#xff0c;虚拟路面VPG技术可以极大地节省载荷谱的获取时间并降低测试成本。 本文将给大家介绍汽车悬挂系统中的…

一文讲解Docker入门到精通

一、引入 1、什么是虚拟化 在计算机中&#xff0c;虚拟化&#xff08;英语&#xff1a;Virtualization&#xff09;是一种资源管理技术&#xff0c;它允许在一台物理机上创建多个独立的虚拟环境&#xff0c;这些环境被称为虚拟机&#xff08;VM&#xff09;。每个虚拟机都可以…

无锁编程——从CPU缓存一致性讲到内存模型(1)

一.前言 1.什么是有锁编程&#xff0c;什么是无锁编程&#xff1f; 在编程中&#xff0c;特别是在并发编程的上下文中&#xff0c;“无锁”和“有锁”是描述线程同步和资源访问控制的两种不同策略。有锁&#xff08;Locked&#xff09;: 有锁编程是指使用锁&#xff08;例如互…

基于JSP技术的校园餐厅管理系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果您对校园餐厅管理系统感兴趣或有相关需求&#xff0c;欢迎随时联系我。我的联系方式在文末&#xff0c;期待与您交流&#xff01; 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#x…

MySQL 8 命令安装卸载教程

一、下载MySQL8 下载连接 MySQL :: Download MySQL Community Server 我下载的是当前最新版8.4 二、安装 1.解压 解压到需要安装的位置&#xff0c;例如我的位置&#xff1a; 2.创建配置文件 新建文本文档&#xff0c;复制下面配置文件&#xff08;注意修改路经&#xff09;…

Cesium大屏-vue3注册全局组件

1.需求 说明&#xff1a;产品经理要求开发人员在地图大屏上面随意放置组件&#xff0c;并且需要通过数据库更改其组件大小&#xff0c;位置等&#xff1b;适用于大屏组件中场站视角、任意位置标题等。 2.实现 2.1GlobalComponents.vue 说明&#xff1a;containerList可以通…

javascript 常见设计模式

什么是设计模式? 在软件开发中&#xff0c;设计模式是解决特定问题的经验总结和可复用的解决方案。设计模式可以提高代码的复用性、可维护性和可读性&#xff0c;是提高开发效率的重要手段。 单例模式 1.概念 单例模式 &#xff08;Singleton Pattern&#xff09;&#xf…

ssm校园二手交易平台小程序

设计技术&#xff1a; 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringMybatisSpringMvc微信小程序 工具&#xff1a;IDEA、Maven、Navicat 主要功能&#xff1a; (a) 管理员&#xff1b;管理员进入系统主要功能包括首页&#xff0c;个人中心&…

RedHat9 | 内部YUM本地源服务器搭建

服务器参数 标识公司内部YUM服务器主机名yum-server网络信息192.168.37.1/24网络属性静态地址主要操作用户root 一、基础环境信息配置 修改主机名 [rootyum-server ~]# hostnamectl hostname yum-server添加网络信息 [rootyum-server ~]# nmcli connection modify ens160 …

红黑树模拟

1.红黑树概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但每个节点上增加了一个存储位表示结点的颜色&#xff0c;可以是RED或BLACK。通过任何一条根到叶子节点的途径上各个节点的着色方式的限制&#xff0c;红黑树确保没有一条路径会超过其他路径的二倍&#xff0c;因…

MySQL InnoDB Cluster 高可用集群部署

MySQL InnoDB Cluster 简介 官方文档&#xff1a;https://dev.mysql.com/doc/refman/8.4/en/mysql-innodb-cluster-introduction.html 本章介绍 MySQL InnoDB Cluster&#xff0c;它结合了 MySQL 技术&#xff0c;使您能够部署和管理完整的 MySQL 集成高可用性解决方案。 说…

SOC模块LoRa-STM32WLE5有哪些值得关注

SoC 是片上系统的缩写&#xff0c;是一种集成芯片&#xff0c;集成了计算机或其他电子系统的所有或大部分组件。这些组件通常包括中央处理器 (CPU)、内存、输入/输出接口和辅助存储接口。包含数字、模拟、混合信号和通常的 RF 信号处理功能&#xff0c;具体取决于应用。片上系统…

优质快刊合集!内含TOP刊、CCF推荐期刊!编辑友好,极速发表!

【SciencePub学术】本期给大家推荐的是几本计算机快刊合集&#xff0c;内含优质TOP刊&#xff0c;现在版面已经所剩不多。且均属于我处目前进展很顺的期刊&#xff0c;大家可以放心投稿&#xff01; 计算机工程类 SCI&#xff08;TOP刊 / CCF-C类&#xff09; 【期刊简介】IF…

高斯过程的数学理解

目录 一、说明 二、初步&#xff1a;多元高斯分布 三、 线性回归模型与维度的诅咒 四、高斯过程的数学背景 五、高斯过程的应用&#xff1a;高斯过程回归 5.1 如何拟合和推理高斯过程模型 5.2 示例&#xff1a;一维数据的高斯过程模型 5.3 示例&#xff1a;多维数据的高斯过程模…

滑动窗口算法系列|基础概念|例题讲解

大家好,我是LvZi,今天带来滑动窗口算法系列|基础概念|例题讲解 一.滑动窗口问题基础概念 滑动窗口本质上是同向双指针问题,脱胎于双指针.使用两个指针l, r维护一定长度的数组区间,在r 指针遍历的过程中,执行进窗口,判断,更新结果,出窗口 等操作,当r指针遍历完毕,就能得到最后…

Study--Oracle-05-Oracler体系结构

一、oracle 体系概览 Oracle数据库的体系结构通常包括以下主要组件&#xff1a; 1、实例&#xff08;Instance&#xff09;&#xff1a;运行数据库的软件环境&#xff0c;包括内存结构&#xff08;SGA&#xff09;和进程结构&#xff08;Background Processes and User Proces…