代码随想录-Day49

300. 最长递增子序列

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的
子序列

示例 1:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:

输入:nums = [0,1,0,3,2,3]
输出:4
示例 3:

输入:nums = [7,7,7,7,7,7,7]
输出:1
在这里插入图片描述

class Solution {
    public int lengthOfLIS(int[] nums) {
        if (nums.length <= 1) return nums.length;
        int[] dp = new int[nums.length];
        int res = 1;
        Arrays.fill(dp, 1);
        for (int i = 1; i < dp.length; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            res = Math.max(res, dp[i]);
        }
        return res;
    }
}

这段代码是用于解决「最长递增子序列」(Longest Increasing Subsequence, LIS)问题的Java实现。给定一个整数数组 nums,目标是找到其中最长的严格递增子序列的长度。这里所说的子序列是指原序列中删除一些或不删除元素且保持剩余元素的相对顺序不变形成的序列。

代码解析

  1. 边界情况处理:

    • 如果 nums 的长度小于等于1,那么最长递增子序列的长度就是数组的长度本身,因为单个元素或空数组本身就是递增的。
  2. 初始化动态规划数组:

    • 创建一个与 nums 长度相等的数组 dp,其中 dp[i] 代表以 nums[i] 结尾的最长递增子序列的长度。初始化 dp 数组的所有元素为1,因为至少每个元素自身都可以构成长度为1的递增子序列。
  3. 动态规划迭代:

    • 从数组的第二个元素开始迭代,对于每一个元素 nums[i](从索引1开始),遍历其前面的所有元素 nums[j](从索引0到 i-1)。
    • 如果当前元素 nums[i] 大于前面的某个元素 nums[j],那么可以尝试构建一个新的递增子序列,其长度为以 nums[j] 结尾的最长递增子序列的长度加1,即 dp[j] + 1
    • 更新 dp[i] 为所有可能的递增子序列长度中的最大值,这确保了 dp[i] 始终保存的是以 nums[i] 结尾的最长递增子序列的长度。
  4. 记录结果:

    • 在每次更新 dp[i] 后,同时更新全局最大值 res,以确保在整个迭代过程中始终保存最长递增子序列的长度。
  5. 返回结果:

    • 最后返回 res,即整个数组中的最长递增子序列的长度。

时间复杂度和空间复杂度

  • 时间复杂度: O(n^2),其中 n 是数组 nums 的长度。这是因为对于数组中的每个元素,都需要遍历其前面的所有元素来计算最长递增子序列的长度。
  • 空间复杂度: O(n),需要一个长度为 n 的动态规划数组 dp 来存储中间结果。

总结

这段代码通过动态规划的方法,有效地解决了最长递增子序列问题。尽管时间复杂度为 O(n^2),但在许多实际应用场景中,这样的性能通常是可接受的。如果需要更高效的算法(如 O(n log n) 的时间复杂度),则可以采用更复杂的算法,例如结合二分查找的优化版本。

674. 最长连续递增序列

给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。

连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], …, nums[r - 1], nums[r]] 就是连续递增子序列。

示例 1:

输入:nums = [1,3,5,4,7]
输出:3
解释:最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。
示例 2:

输入:nums = [2,2,2,2,2]
输出:1
解释:最长连续递增序列是 [2], 长度为1。
在这里插入图片描述

方法一:动态规划

 /**
     * 1.dp[i] 代表当前下标最大连续值
     * 2.递推公式 if(nums[i+1]>nums[i]) dp[i+1] = dp[i]+1
     * 3.初始化 都为1
     * 4.遍历方向,从其那往后
     * 5.结果推导 。。。。
     * @param nums
     * @return
     */
    public static int findLengthOfLCIS(int[] nums) {
        int[] dp = new int[nums.length];
        for (int i = 0; i < dp.length; i++) {
            dp[i] = 1;
        }
        int res = 1;
	//可以注意到,這邊的 i 是從 0 開始,所以會出現和卡哥的C++ code有差異的地方,在一些地方會看到有 i + 1 的偏移。
        for (int i = 0; i < nums.length - 1; i++) {
            if (nums[i + 1] > nums[i]) {
                dp[i + 1] = dp[i] + 1;
            }
            res = res > dp[i + 1] ? res : dp[i + 1];
        }
        return res;
    }

这段代码是用于解决「最长连续递增序列」(Longest Continuous Increasing Subsequence, LCIS)问题的Java实现。给定一个整数数组 nums,目标是找到其中最长的连续严格递增序列的长度。

代码解析

  1. 初始化动态规划数组:

    • 创建一个与 nums 长度相等的数组 dp,其中 dp[i] 代表以 nums[i] 结尾的最长连续递增序列的长度。初始化 dp 数组的所有元素为1,因为至少每个元素自身都可以构成长度为1的连续递增序列。
  2. 动态规划迭代:

    • 从数组的第一个元素开始迭代,直到倒数第二个元素(因为需要比较当前元素与其下一个元素的关系),对于每一个元素 nums[i](从索引0开始到 nums.length - 2)。
    • 如果当前元素 nums[i] 小于其下一个元素 nums[i + 1],那么可以构建一个新的连续递增序列,其长度为以 nums[i] 结尾的最长连续递增序列的长度加1,即 dp[i] + 1
    • 更新 dp[i + 1] 为这个新的连续递增序列的长度。
  3. 记录结果:

    • 在每次更新 dp[i + 1] 后,同时更新全局最大值 res,以确保在整个迭代过程中始终保存最长连续递增序列的长度。
  4. 返回结果:

    • 最后返回 res,即整个数组中的最长连续递增序列的长度。

特别注意

在迭代过程中,由于 dp 数组的更新是基于前一个元素的值,因此迭代的方向是从前往后,这确保了在更新 dp[i + 1] 时,dp[i] 已经包含了正确的信息。

时间复杂度和空间复杂度

  • 时间复杂度: O(n),其中 n 是数组 nums 的长度。这是因为只需要遍历数组一次来计算最长连续递增序列的长度。
  • 空间复杂度: O(n),需要一个长度为 n 的动态规划数组 dp 来存储中间结果。

总结

这段代码通过动态规划的方法,有效地解决了最长连续递增序列问题。相比于最长递增子序列问题,最长连续递增序列问题的时间复杂度更低,因为不需要对每个元素都进行前面所有元素的比较,只需关注相邻元素之间的关系。

方法二:动态规划状态压缩

class Solution {
    public int findLengthOfLCIS(int[] nums) {
        // 记录以 前一个元素结尾的最长连续递增序列的长度 和 以当前 结尾的......
        int beforeOneMaxLen = 1, currentMaxLen = 0;
        // res 赋最小值返回的最小值1
        int res = 1;
        for (int i = 1; i < nums.length; i ++) {
            currentMaxLen = nums[i] > nums[i - 1] ? beforeOneMaxLen + 1 : 1;
            beforeOneMaxLen = currentMaxLen;
            res = Math.max(res, currentMaxLen);
        }
        return res;
    }
}

这段代码是解决「最长连续递增序列」(Longest Continuous Increasing Subsequence, LCIS)问题的另一种高效实现,它采用了空间优化的动态规划方法。给定一个整数数组 nums,目标是找到其中最长的连续严格递增序列的长度。

代码解析

  1. 初始化变量:

    • beforeOneMaxLen:表示以当前元素的前一个元素结尾的最长连续递增序列的长度。
    • currentMaxLen:表示以当前元素结尾的最长连续递增序列的长度。初始化时,这个变量没有实际意义,因为真正的计算在循环中进行。
    • res:用于记录整个数组中的最长连续递增序列的长度,初始化为1,因为至少每个元素自身都可以构成长度为1的连续递增序列。
  2. 动态规划迭代:

    • 从数组的第二个元素开始迭代,对于每一个元素 nums[i](从索引1开始到 nums.length - 1)。
    • 如果当前元素 nums[i] 大于其前一个元素 nums[i - 1],那么可以构建一个新的连续递增序列,其长度为以 nums[i - 1] 结尾的最长连续递增序列的长度加1,即 beforeOneMaxLen + 1
    • 如果当前元素不大于其前一个元素,那么以当前元素结尾的最长连续递增序列的长度重置为1,因为连续递增被中断,新的连续递增序列从当前元素开始。
    • 更新 beforeOneMaxLencurrentMaxLen,以准备下一次迭代。
  3. 记录结果:

    • 在每次更新 currentMaxLen 后,同时更新全局最大值 res,以确保在整个迭代过程中始终保存最长连续递增序列的长度。
  4. 返回结果:

    • 最后返回 res,即整个数组中的最长连续递增序列的长度。

特别注意

与之前版本相比,这段代码在空间复杂度上进行了优化,不再需要一个与输入数组相同长度的动态规划数组 dp,而是仅使用几个变量来保存必要的状态信息,这大大减少了空间占用。

时间复杂度和空间复杂度

  • 时间复杂度: O(n),其中 n 是数组 nums 的长度。这是因为只需要遍历数组一次来计算最长连续递增序列的长度。
  • 空间复杂度: O(1),仅使用了固定数量的变量,与输入数组的大小无关。

总结

这段代码通过动态规划的方法,有效地解决了最长连续递增序列问题,同时在空间复杂度方面进行了优化,使得算法更加高效。相比于传统的动态规划实现,这种空间优化的方法在处理大规模数据时表现更佳。

方法三:贪心法

public static int findLengthOfLCIS(int[] nums) {
    if (nums.length == 0) return 0;
    int res = 1; // 连续子序列最少也是1
    int count = 1;
    for (int i = 0; i < nums.length - 1; i++) {
        if (nums[i + 1] > nums[i]) { // 连续记录
            count++;
        } else { // 不连续,count从头开始
            count = 1;
        }
        if (count > res) res = count;
    }
    return res;
}

这段代码是解决「最长连续递增序列」(Longest Continuous Increasing Subsequence, LCIS)问题的简洁实现。给定一个整数数组 nums,目标是找到其中最长的连续严格递增序列的长度。

代码解析

  1. 边界情况处理:

    • 如果 nums 的长度为0,那么最长连续递增序列的长度自然为0。
  2. 初始化变量:

    • res:用于记录整个数组中的最长连续递增序列的长度,初始化为1,因为至少每个元素自身都可以构成长度为1的连续递增序列。
    • count:表示当前正在统计的连续递增序列的长度,初始化为1。
  3. 动态检查与更新:

    • 从数组的第一个元素开始迭代,直到倒数第二个元素,对于每一个元素 nums[i](从索引0开始到 nums.length - 2)。
    • 如果当前元素 nums[i] 小于其下一个元素 nums[i + 1],那么当前正在统计的连续递增序列的长度 count 加1。
    • 如果当前元素不小于其下一个元素,那么当前连续递增序列被中断,count 重置为1,从下一个元素重新开始统计新的连续递增序列的长度。
  4. 记录结果:

    • 在每次更新 count 后,同时更新全局最大值 res,以确保在整个迭代过程中始终保存最长连续递增序列的长度。
  5. 返回结果:

    • 最后返回 res,即整个数组中的最长连续递增序列的长度。

时间复杂度和空间复杂度

  • 时间复杂度: O(n),其中 n 是数组 nums 的长度。这是因为只需要遍历数组一次来计算最长连续递增序列的长度。
  • 空间复杂度: O(1),仅使用了固定数量的变量,与输入数组的大小无关。

总结

这段代码通过简单直观的方式,有效地解决了最长连续递增序列问题。相比于使用动态规划数组的传统方法,这段代码不仅易于理解和实现,而且在空间复杂度方面表现出色,仅使用了几个变量,非常适合处理大规模数据集。此外,这种方法避免了动态规划中可能存在的冗余计算,提高了算法的效率。

718. 最长重复子数组

给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 。

示例 1:

输入:nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
输出:3
解释:长度最长的公共子数组是 [3,2,1] 。
示例 2:

输入:nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0]
输出:5
在这里插入图片描述

方法一:

// 版本一
class Solution {
    public int findLength(int[] nums1, int[] nums2) {
        int result = 0;
        int[][] dp = new int[nums1.length + 1][nums2.length + 1];
        
        for (int i = 1; i < nums1.length + 1; i++) {
            for (int j = 1; j < nums2.length + 1; j++) {
                if (nums1[i - 1] == nums2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    result = Math.max(result, dp[i][j]);
                }
            }
        }
        
        return result;
    }
}

这段代码是用于解决「两个数组的最长相同子数组」问题的Java实现。给定两个整数数组 nums1nums2,目标是找到在这两个数组中都出现的最长连续相同子数组的长度。

代码解析

  1. 初始化动态规划数组:

    • 创建一个二维数组 dp,其大小为 (nums1.length + 1) x (nums2.length + 1)dp[i][j] 的值代表以 nums1[i-1]nums2[j-1] 结尾的最长连续相同子数组的长度。额外的一列和一行是为了方便边界条件的处理。
  2. 动态规划迭代:

    • 从数组的第一个有效元素开始迭代,对于每一个元素 nums1[i-1]nums2[j-1](从索引1开始到 nums1.lengthnums2.length)。
    • 如果 nums1[i-1] 等于 nums2[j-1],那么以它们结尾的最长连续相同子数组的长度等于以它们的前一个元素结尾的最长连续相同子数组的长度加1,即 dp[i-1][j-1] + 1
    • 如果两个元素不相等,那么 dp[i][j] 的值为0,因为当前元素不能扩展任何一个连续相同子数组。
  3. 记录结果:

    • 在每次更新 dp[i][j] 后,同时更新全局最大值 result,以确保在整个迭代过程中始终保存最长连续相同子数组的长度。
  4. 返回结果:

    • 最后返回 result,即两个数组中都出现的最长连续相同子数组的长度。

时间复杂度和空间复杂度

  • 时间复杂度: O(m * n),其中 m 和 n 分别是数组 nums1nums2 的长度。这是因为需要遍历两个数组的所有可能的元素组合来计算最长连续相同子数组的长度。
  • 空间复杂度: O(m * n),需要一个大小为 (m + 1) x (n + 1) 的动态规划数组 dp 来存储中间结果。

总结

这段代码通过动态规划的方法,有效地解决了两个数组的最长相同子数组问题。尽管时间复杂度和空间复杂度较高,但在许多实际应用场景中,这样的性能通常是可接受的,特别是当数组大小适中时。如果需要进一步优化空间复杂度,可以考虑使用滚动数组技术,将空间复杂度降低到 O(min(m, n))。

方法二:

// 版本二: 滚动数组
class Solution {
    public int findLength(int[] nums1, int[] nums2) {
        int[] dp = new int[nums2.length + 1];
        int result = 0;

        for (int i = 1; i <= nums1.length; i++) {
            for (int j = nums2.length; j > 0; j--) {
                if (nums1[i - 1] == nums2[j - 1]) {
                    dp[j] = dp[j - 1] + 1;
                } else {
                    dp[j] = 0;
                }
                result = Math.max(result, dp[j]);
            }
        }
        return result;
    }
}

这段代码是用于解决「两个数组的最长相同子数组」问题的Java实现,特别之处在于它使用了滚动数组技术来优化空间复杂度。给定两个整数数组 nums1nums2,目标是找到在这两个数组中都出现的最长连续相同子数组的长度。

代码解析

  1. 初始化动态规划数组:

    • 创建一个一维数组 dp,其大小为 nums2.length + 1dp[j] 的值代表以 nums1[i-1]nums2[j-1] 结尾的最长连续相同子数组的长度,其中 i 是外层循环的索引。额外的一列是为了方便边界条件的处理。
  2. 动态规划迭代:

    • 外层循环从1到 nums1.length 遍历 nums1 的每个元素。
    • 内层循环从 nums2.length 反向遍历到1,对于每个 nums2[j-1]
    • 如果 nums1[i-1] 等于 nums2[j-1],那么以它们结尾的最长连续相同子数组的长度等于以 nums2[j-2] 结尾的最长连续相同子数组的长度加1,即 dp[j - 1] + 1
    • 如果两个元素不相等,那么 dp[j] 的值为0。
    • 注意内层循环从后向前遍历的原因是为了避免在更新 dp[j] 的时候影响到尚未处理的 dp[j-1] 的值,因为外层循环中的 i 不断增加,而内层循环中的 j 不断减少,这样可以确保 dp[j-1] 总是保留着前一个状态的正确值。
  3. 记录结果:

    • 在每次更新 dp[j] 后,同时更新全局最大值 result,以确保在整个迭代过程中始终保存最长连续相同子数组的长度。
  4. 返回结果:

    • 最后返回 result,即两个数组中都出现的最长连续相同子数组的长度。

时间复杂度和空间复杂度

  • 时间复杂度: O(m * n),其中 m 和 n 分别是数组 nums1nums2 的长度。这是因为需要遍历两个数组的所有可能的元素组合来计算最长连续相同子数组的长度。
  • 空间复杂度: O(n),其中 n 是 nums2 的长度。使用了一维数组 dp 来存储中间结果,相比于版本一的二维数组,空间复杂度显著降低。

总结

这段代码通过滚动数组的动态规划方法,有效地解决了两个数组的最长相同子数组问题,同时在空间复杂度方面进行了优化。滚动数组技术避免了使用额外的大量空间,使得算法在处理大规模数据时更加高效。

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

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

相关文章

进程控制-fork函数

一个进程&#xff0c;包括代码、数据和分配给进程的资源。 fork &#xff08;&#xff09;函数通过系统调用创建一个与原来进程几乎完全相同的进程&#xff0c;也就是两个进程可以做完全相同的事&#xff0c;但如果初始参数或者传入的变量不同&#xff0c;两个进程也可以做不同…

第十六章 Qt的文件处理操作详解

目录 一、基本文件操作 二、二进制文件读写 三、文本文件读写 四、操作例子 1、QTextStream的流操作符 一、基本文件操作 文件操作是应用程序必不可少的部分。Qt 作为一个通用开发库,提供了跨平台的文件操作能力。在所有的 I/O 设备中,文件 I/O 是最重要的部分之…

InfluxDB时序数据库基本使用介绍

1、概要介绍 1.1、时序数据库使用场景 所谓时序数据库就是按照一定规则的时间序列进行数据读写操作的数据库。它们常被用于以下业务场景&#xff1a; 物联网IOT场景&#xff1a;可用于IOT设备的指标、状态监控数据存取。IT建设场景&#xff1a;可用于服务器、虚拟机、容器的…

linux下的网络编程

网络编程 1. 网络基础编程知识1.1网络字节序问题1.2 常用socket编程接口1.2.1 sockaddr1.2.2 ip地址转换函数1.2.4 socket()1.2.3 bind()1.2.4 listen()1.2.5 accept()1.2.6 connect() 1.3 以udp为基础的客户端连接服务器的demo1.4 以udp为基础的的服务器聊天室功能demo1.5 基于…

解决vscode配置C++编译带有中文名称报错问题

在新电脑上安装vscode运行带有中文路径和中文名称的C代码时遇到报错 根据别人的教程将laugh.json文件中"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",改成了"program": "${fileDirname}\\output\\test.exe",&#x…

聊天广场(Vue+WebSocket+SpringBoot)

由于心血来潮想要做个聊天室项目 &#xff0c;但是仔细找了一下相关教程&#xff0c;却发现这么多的WebSocket教程里面&#xff0c;很多都没有介绍详细&#xff0c;代码都有所残缺&#xff0c;所以这次带来一个比较完整得使用WebSocket的项目。 目录 一、效果展示 二、准备工…

大数据中的常见数据问题:独断脏

想象你刚刚入职一家声称正在进行"数字化转型"的大型企业,担任大数据开发工程师。在入职的第一周,你满怀热情,迫不及待地想要大展拳脚,用你的技能来推动公司的数据驱动决策。 目录 大数据中的常见数据问题1. 独 - 数据孤岛2. 断 - 数据价值链断层3. 缺 - 标准、治理…

并口、串口和GPIO口区别

并口 并行接口,简称并口。并口采用的是25针D形接头。所谓“并行”,是指8位数据同时通过并行线进行传送,这样数据传送速度大大提高,但并行传送的线路长度受到限制,因为长度增加,干扰就会增加,数据也就容易出错,目前,并行接口主要作为打印机端口等。 并口的工作模式 …

ctfshow web 36d 练手赛

不知所措.jpg 没啥用然后测试了网站可以使用php伪达到目的 ?filephp://filter/convert.base64-encode/resourcetest/../index.<?php error_reporting(0); $file$_GET[file]; $file$file.php; echo $file."<br />"; if(preg_match(/test/is,$file)){inclu…

安全测试之使用Docker搭建SQL注入安全测试平台sqli-labs

1 搜索镜像 docker search sqli-labs 2 拉取镜像 docker pull acgpiano/sqli-labs 3 创建docker容器 docker run -d --name sqli-labs -p 10012:80 acgpiano/sqli-labs 4 访问测试平台网站 若直接使用虚拟机&#xff0c;则直接通过ip端口号访问若通过配置域名&#xff0…

【论文笔记】UniST:通用预训练城市时空预测模型

目录 写在前面1. 通用时空模型的挑战与能力特性2. 构建通用时空模型UniST2.1 大规模时空预训练2.2 时空知识规则引导提示学习 3. UniST的实验与分析3.1 模型预测效果3.2其他实验分析 写在前面 文章标题&#xff1a;UniST: A Prompt-Empowered Universal Model for Urban Spati…

基于SpringBoot+Vue的招生管理系统(带1w+文档)

基于SpringBootVue的招生管理系统(带1w文档&#xff09; 通过招生管理系统的研究可以更好地理解系统开发的意义&#xff0c;而且也有利于发展更多的智能系统&#xff0c;解决了人才的供给和需求的平衡问题&#xff0c;招生管理系统的开发建设&#xff0c;由于其开发周期短&…

linux centos 安装niginx并且添加ssl(https)模块

文章目录 前言一、nginx安装教程1.流程步骤 总结 前言 一、nginx安装教程 1.流程步骤 代码如下&#xff08;示例&#xff09;&#xff1a; 1.先下载linux安装包 2.解压安装命令 sudo tar -zxvf nginx-1.20.1.tar.gz3.进入解压后的目录 sudo cd nginx-1.20.14.安装 sudo y…

AntDesign上传组件upload二次封装+全局上传hook使用

文章目录 前言a-upload组件二次封装1. 功能分析2. 代码详细注释3. 使用到的全局上传hook代码4. 使用方式5. 效果展示 总结 前言 在项目中&#xff0c;ant-design是我们常用的UI库之一&#xff0c;今天就来二次封装常用的组件a-upload批量上传组件,让它用起来更方便。 a-uploa…

C++ | Leetcode C++题解之第213题打家劫舍II

题目&#xff1a; 题解&#xff1a; class Solution { public:int robRange(vector<int>& nums, int start, int end) {int first nums[start], second max(nums[start], nums[start 1]);for (int i start 2; i < end; i) {int temp second;second max(fi…

Nacos服务注册总流程(源码分析)

文章目录 服务注册NacosClient找看源码入口NacosClient服务注册源码NacosServer处理服务注册 服务注册 服务注册 在线流程图 NacosClient找看源码入口 我们启动一个微服务&#xff0c;引入nacos客户端的依赖 <dependency><groupId>com.alibaba.cloud</groupI…

工作两年后,我如何看待设计模式

在软件工程中&#xff0c;设计模式是经过反复验证的最佳实践&#xff0c;用于解决在软件设计中经常遇到的一类问题。它们为开发者提供了一种通用的解决方案和语言&#xff0c;使得复杂的编程问题得以简化&#xff0c;代码结构更加清晰&#xff0c;可维护性大大提高。简而言之&a…

PostgreSQL 如何优化存储过程的执行效率?

文章目录 一、查询优化1. 正确使用索引2. 避免不必要的全表扫描3. 使用合适的连接方式4. 优化子查询 二、参数传递1. 避免传递大对象2. 参数类型匹配 三、减少数据量处理1. 限制返回结果集2. 提前筛选数据 四、优化逻辑结构1. 分解复杂的存储过程2. 避免过度使用游标 五、事务处…

隐私计算实训营第二期第七课:XGB算法与SGB算法开发实践

隐私计算实训营第二期-第七课 第七课&#xff1a;XGB算法与SGB算法开发实践1 决策树模型1.1 决策树的训练和预测过程1.2 决策树的发展过程 2 GBDT模型2.1 Boosting核心思想2.2 GBDT原理 3 XGB模型3.1 XGB核心思想3.2 XGB优点 3 隐语纵向树模型3.1 数据纵向分割3.2 隐私保护的树…

本地部署到服务器上的资源路径问题

本地部署到服务器上的资源路径问题 服务器端的源代码的静态资源目录层级 当使用Thymeleaf时&#xff0c;在templates的目录下为返回的html页面&#xff0c;下面以两个例子解释当将代码部署到tomcat时访问资源的路径配置问题 例子一 index.html&#xff08;在templates的根目录…