动态规划 典型例题

news2025/4/22 8:31:50

总结

动态规划的的四个解题步骤是:

  • 定义子问题
  • 写出子问题的递推关系
  • 确定 DP 数组的计算顺序
  • 空间优化(可选)
from functools import cache
@cache #缓存,避免重复运算
def dfs(i)->int:
	if 终止: return 0 #具体返回什么值要看题目的含义
	cnt = 0
    for 递归方向:
        cnt += dfs(xxx) #如果是计数,一般是叠加,也有可能是取最大或者最小
    return cnt

509 F 数列

注意:

f0 = 0, f1 = 0, f2 = 1

class Solution:
    def fib(self, n: int) -> int:
        if n < 2:
            return n

        p, q, r = 0, 0, 1
        for i in range(2, n + 1):
            p, q = q, r
            r = p + q
        
        return r

198 打家劫舍

class Solution:
    def rob(self, nums: List[int]) -> int:

        N = len(nums)
        dp = [0] * (N + 1)
        # dp[i]  [0, i) 家里面能偷得的最大金额
        dp[0] = 0
        dp[1] = nums[0]
        for k in range(2, N + 1):
            dp[k] = max(dp[k - 1], nums[k - 1] + dp[k - 2]);
        return dp[N]

64 最小路径和

class Solution:
    def minPathSum(self, grid: List[List[int]]) -> int:
        if not grid or not grid[0]:
            return 0
        
        rows, columns = len(grid), len(grid[0])
        # 注意可以这样初始化
        dp = [[0] * columns for _ in range(rows)]
        dp[0][0] = grid[0][0]
        for i in range(1, rows):
            dp[i][0] = dp[i - 1][0] + grid[i][0]
        for j in range(1, columns):
            dp[0][j] = dp[0][j - 1] + grid[0][j]
        for i in range(1, rows):
            for j in range(1, columns):
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
        
        return dp[rows - 1][columns - 1]

62 不同路径

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp = [[1] * n] + [[1] + [0] * (n - 1) for _ in range(m - 1)]
        for i in range(1, m):
            for j in range(1, n):
                f[i][j] = f[i - 1][j] + f[i][j - 1]
        return f[m - 1][n - 1]

63 有障碍物的不同路径

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid):
        m = len(obstacleGrid)
        n = len(obstacleGrid[0])

        dp = [[0] * n for _ in range(m)]

        if obstacleGrid[0][0] != 1:
            dp[0][0] = 1

        # 给第一行赋值
        for i in range(1, n):
            if obstacleGrid[0][i] != 1:
                dp[0][i] = dp[0][i - 1]

        # 给第一列赋值
        for j in range(1, m):
            if obstacleGrid[j][0] != 1:
                dp[j][0] = dp[j - 1][0]

        for i in range(1, m):
            for j in range(1, n):
                # 关键判断
                if obstacleGrid[i][j] != 1:
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

        return dp[m - 1][n - 1]

118 杨辉三角

行号从 1 开始,列从 0 开始

class Solution:
    def generate(self, numRows):
        # f[i][j]: 第 i 行第 j 个元素的值
        # f[i][j] = f[i - 1][j - 1] + f[i - 1][j]
        # 注意给边界赋值
        dp = []
        dp.append([1])
        
        # numRows > 1
        for i in range(1, numRows):
            dp.append([0] * (i + 1))
            for j in range(i + 1):
                if j == 0 or j == i:
                    dp[i][j] = 1
                else:
                    dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]

        return dp

120 杨辉三角的变体

class Solution:
    def minimumTotal(self, triangle):
        # f[i][j] : 到达第 i 行 j 个元素的最小路径
        # f = min(f[i - 1][j - 1], f[i - 1][j]) + triangle[i][j]
        # 边界只能累加

        m = len(triangle)
        dp = [triangle[0]]

        # 类似杨辉
        # 行列都是从 0 开始计数
        for i in range(1, m):
            dp.append([0] * (i + 1))
            for j in range(i + 1):
                if j == 0:
                    dp[i][j] = dp[i - 1][j] + triangle[i][j]
                elif j == i:
                    dp[i][j] = dp[i - 1][j - 1] + triangle[i][j]
                else:
                    dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j]

        # 找到最下面一行的最小值
        ans = float('inf')
        for i in range(m):
            ans = min(ans, dp[m - 1][i])

        return ans

279 完全平方数

import math

class Solution:
    def numSquares(self, n: int) -> int:
        """
        求 f(n): 和为 n 的完全平方数的最少数量 
        f(n) = f(n - j ^ 2) + 1
        j^2 <= n

        f(1) = 1
        f(2) = f(2 - 1) + 1 = 2
        f(3) = min(f(3 - 1)) + 1 = 3;
        f(4) = f(0) + 1 or f(3) + 1
        """

        # 初始化动态规划数组,储存和为 i 的最少完全平方数数量
        # 数值范围 1 -- n
        dp = [0] * (n + 1)
        dp[1] = 1  # 初始条件,和为 1 的最少数量为 1

        # 遍历计算从 2 到 n 的和为 i 的最少完全平方数数量
        for i in range(2, n + 1):
            s = int(math.sqrt(i))  # 计算 i 的平方根,作为循环的上界
            ans = float('inf')  # 初始化 ans 为正无穷,用于记录最小数量
            for j in range(s, 0, -1):
                ans = min(ans, dp[i - j * j] + 1)  # 更新最小数量
            dp[i] = ans  # 记录和为 i 的最小数量

        return dp[n]  # 返回和为 n 的最小完全平方数数量

377 组合总和

不需要去重

class Solution:
    def combinationSum4(self, nums, target):
        """
        f[i] = nums 中可以组合为 i 的元素组合的个数
        f[i] = Σf[i - nums[j]]
        初始化为1
        """
        dp = [0] * (target + 1)
        dp[0] = 1

        for i in range(1, target + 1):
            for num in nums:
                if num <= i and dp[i] < float('inf') - dp[i - num]:
                    dp[i] += dp[i - num]

        return dp[target]

300 最长递增子序列*

以下标 i 的元素结尾的最长递增子序列的长度

class Solution:
    def lengthOfLIS(self, nums):
        """
        dp[i] 以下标为 i 的数结尾的最长递增子序列的长度
        """
        dp = [1] * len(nums)

        for i in range(1, len(nums)):
            for j in range(i):
                if nums[j] < nums[i]:
                    dp[i] = max(dp[i], dp[j] + 1)

        return max(dp)

674 最长连续递增子序列*

class Solution:
    def findLengthOfLCIS(self, nums: List[int]) -> int:

        dp = [0] * len(nums)
        ans = 1

        for i in range(1, len(nums)):
            if nums[i] > nums[i - 1]:
                dp[i] = dp[i - 1] + 1
                ans = max(ans, dp[i])
        return ans

718 最长公共子串

class Solution:
    def findLength(self, nums1, nums2):
        """
        f(i, j) 包含 nums1 的第 i 个数字和包含 nums2 的第 j 个数字的最长重复子数组的长度
        if nums1[i] == nums2[j]
            f(i, j) = f(i - 1, j - 1) + 1
        else:
            f(i, j) = 0
        """

        # 第一行和第一列表示不取任何数字
        dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)]

        ans = 0
        # 遍历行
        for i in range(1, len(nums1) + 1):
            # 遍历列
            for j in range(1, len(nums2) + 1):
                if nums1[i - 1] == nums2[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1] + 1
                # 肯定不是最长公共子串
                else:
                    dp[i][j] = 0
                ans = max(ans, dp[i][j])
        return ans

1143 最长公共子序列

可以不连续,所以else后面有差异

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        len1 = len(text1)
        len2 = len(text2)

        dp = [[0] * (len2 + 1) for _ in range(len1 + 1)]

        for i in range(1, len1 + 1):
            for j in range(1, len2 + 1):
                if text1[i - 1] == text2[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1] + 1
                else:
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

        
        return dp[len1][len2]

583 两个字符串的删除操作

class Solution:
    def minDistance(self, word1, word2):
        """
        f(i, j) 将 s1 的前 i 个字符和 s2 的前 j 个字符变为相同的最小操作数

        if s1[i] == s2[j]
            f[i - 1, j - 1]
        else
            min (f[i - 1, j], f[i, j - 1]) + 1
        f[0, j] = j
        f[i, 0] = i
        """

        len1 = len(word1)
        len2 = len(word2)

        dp = [[0] * (len2 + 1) for _ in range(len1 + 1)]

        for j in range(len2 + 1):
            dp[0][j] = j
        for i in range(len1 + 1):
            dp[i][0] = i

        for i in range(1, len1 + 1):
            for j in range(1, len2 + 1):
                if word1[i - 1] == word2[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1]
                else:
                    dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1

        return dp[len1][len2]

72 编辑距离

大体和上一题类似,操作有三种

class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        """
        f(i, j) : word1 的前 i 个转到 word2 的前 j 个

        插入
        f(i, j) = f(i, j - 1) + 1

        删除
        f(i, j) = f(i - 1, j) + 1

        替换
        f(i, j) = f(i - 1, j - 1) + 1

        相等
        f(i, j) = f(i - 1, j - 1)

        f(0, j) = j
        f(i, 0) = i
        """

        len1 = len(word1)
        len2 = len(word2)

        dp = [[0] * (len2 + 1) for _ in range(len1 + 1)]

        for i in range(len1 + 1):
            dp[i][0] = i
        for i in range(len2 + 1):
            dp[0][i] = i

        for i in range(1, len1 + 1):
            for j in range(1, len2 + 1):
                if word1[i - 1] == word2[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1]
                else:
                    dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1

        return dp[len1][len2]

647 回文子串

考虑子串长度

1个

2个

3个及以上

class Solution:
    def countSubstrings(self, s: str) -> int:
        """
        f(i, j) i 到 j 的子串是否为回文串 0 -- n - 1
            1. s[i] = s[j] && f(i + 1, j - 1)
            i + 1 <= j - 1 ==> i + 2 <= j

            2. 单独算 i + 1 = j, i = j
        """

        n = len(s)
        cnt = 0

        dp = [[False] * n for _ in range(n)]
        for j in range(n):
            for i in range(j, -1, -1):
                # base case
                # 只有一个字符
                if i == j:
                    dp[i][j] = True
                elif i + 1 == j:
                    dp[i][j] = (s[i] == s[j])
                else:
                    dp[i][j] = s[i] == s[j] and dp[i + 1][j - 1]

                if dp[i][j] == True:
                    cnt += 1

        return cnt

516 最长回文子序列

class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        len_s = len(s)
        dp = [[0] * len_s for _ in range(len_s)]

        for j in range(len_s):
            for i in range(j, -1, -1):
                if i == j:
                    dp[i][j] = 1
                elif i + 1 == j:
                    dp[i][j] = 2 if s[i] == s[j] else 1
                else:
                    if s[i] == s[j]:
                        dp[i][j] = dp[i + 1][j - 1] + 2
                    else:
                        dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])

        return dp[0][len_s - 1]

416 0-1 背包 分割等和子集

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        # 求和
        total_sum = sum(nums)

        if total_sum % 2 == 1:
            return False

        target = total_sum // 2

        # 能否凑出半个 0-1 背包
        # 考虑前 i 个数字能否凑出 j
        # f(i, j) = f(i - 1, j) or f(i - 1, j - nums[i])
        # base case: f(0, j): f(0, 0) = True

        dp = [[False] * (target + 1) for _ in range(len(nums) + 1)]
        dp[0][0] = True

        # 从前 i 个数开始
        for i in range(1, len(nums) + 1):
            for j in range(target + 1):
                if nums[i - 1] <= j:
                    dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i - 1]]
                else:
                    # 如果不选
                    dp[i][j] = dp[i - 1][j]

        return dp[len(nums)][target]

优化

第一个维度删掉,第二个反过来

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        # 求和
        total_sum = sum(nums)

        if total_sum % 2 == 1:
            return False

        target = total_sum // 2

        # 能否凑出半个 0-1 背包

        # 考虑前 i 个数字能否凑出 j
        # f(i, j) = f(i - 1, j) or f(i - 1, j - nums[i])
        # base case: f(0, j): f(0, 0) = True

        # 优化
        # 删除第一个维度,第二层反过来
        dp = [False] * (target + 1)
        dp[0] = True

        # 从前 i 个数开始
        for num in nums:
            for j in range(target, num - 1, -1):
                dp[j] = dp[j] or dp[j - num]

        return dp[target]
class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        # 求和
        total_sum = sum(nums)

        if total_sum % 2 == 1:
            return False

        target = total_sum // 2

        # 能否凑出半个 0-1 背包
        # 考虑前 i 个数字能否凑出 j
        # f(i, j) = f(i - 1, j) or f(i - 1, j - nums[i])
        # base case: f(0, j): f(0, 0) = True

        dp = [False] * (target + 1)
        dp[0] = True

        # 从前 i 个数开始
        for i in range(1, len(nums) + 1):
            for j in range(target, nums[i - 1] - 1, -1):
                    dp[j] = dp[j] or dp[j - nums[i - 1]]


        return dp[target]

494 目标和

pos - (sum - pos) = target

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        total_sum = sum(nums)

        if (total_sum + target) % 2 == 1 or total_sum + target < 0:
            return 0

        pos = (total_sum + target) // 2

        """
        f(i, j) 考虑前 i 个数字,凑出 j 有多少种方案
        f(i, j) = f(i-1, j) + f(i-1, j-nums[i])
        f(0, 0) = 1, f(0, j) = 1
        """
        n = len(nums)
        # dp = [[0] * (pos + 1) for _ in range(n + 1)]
        # # 没有数字
        # dp[0][0] = 1

        # for i in range(1, n + 1):
        #     for j in range(pos + 1):
        #         if nums[i - 1] <= j:
        #             dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i - 1]]
        #         else:
        #             dp[i][j] = dp[i - 1][j]
        # return dp[n][pos]

        dp = [0] * (pos + 1) 
        # 没有数字
        dp[0] = 1

        for i in range(1, n + 1):
            for j in range(pos, nums[i - 1] - 1, -1):
                dp[j] = dp[j] + dp[j - nums[i - 1]]
  
        return dp[pos]

474 一和零 0-1 三维-->二维

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        length = len(strs)
        # 开两个背包的容量
        dp = [[0] * (n + 1) for _ in range(m + 1)]

        """
        前 i 个字符串最多 j 个 0 和 k 个 1,可以选的最多字符串数量
        f(i,j,k) = max(f(i - 1, j, k), f(i - 1, j - zero, k - one) + 1)
        f(0, j, k) = 0

        0-1 逆序
        """

        for i in range(1, length + 1):
            # 统计字符串的数量
            zero, one = 0, 0
            for c in strs[i - 1]:
                if c == '0':
                    zero += 1
                else:
                    one += 1
            # 逆序
            for j in range(m, zero - 1, -1):
                for k in range(n, one - 1, -1):
                    dp[j][k] = max(dp[j][k], dp[j - zero][k - one] + 1)

        return dp[m][n]
class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        length = len(strs)
        # 开两个背包的容量
        dp = [[0] * (n + 1) for _ in range(m + 1)]

        """
        前 i 个字符串最多 j 个 0 和 k 个 1,可以选的最多字符串数量
        f(i,j,k) = max(f(i - 1, j, k), f(i - 1, j - zero, k - one) + 1)
        f(0, j, k) = 0

        0-1 逆序
        """

        for i in range(1, length + 1):
            zero, one = 0, 0
            for c in strs[i - 1]:
                if c == '0':
                    zero += 1
                else:
                    one += 1

            for j in range(m, zero - 1, -1):
                for i in range(n, one - 1, -1):
                    dp[j][i] = max(dp[j][i], dp[j - zero][i - one] + 1)
        return dp[m][n]

322 零钱兑换 完全背包

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        """
        前 i 个硬币凑出 amount 的最小数量
        f(i, j) = min(f(i - 1, j), f(i - 1, j - coins[i - 1]) + 1)
        f(0, j) f(0, 0) = 0 else = inf
        """
        n = len(coins)
        dp = [[0] * (amount + 1) for _ in range(n + 1)]
        dp[0][0] = 0
        for j in range(1, amount + 1):
            dp[0][j] = 10010

        for i in range(1, n + 1):
            for j in range(0, amount + 1):
                if coins[i - 1] <= j:
                    dp[i][j] = min(dp[i - 1][j], dp[i][j - coins[i - 1]] + 1)
                else:
                    dp[i][j] = dp[i - 1][j]
                

        return -1 if dp[n][amount] > amount else dp[n][amount]

正序

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        """
        前 i 个硬币凑出 amount 的最小数量
        f(i, j) = min(f(i - 1, j), f(i - 1, j - coins[i - 1]) + 1)
        f(0, j) f(0, 0) = 0 else = inf
        """
        n = len(coins)
        dp = [0] * (amount + 1)
        dp[0] = 0
        for j in range(1, amount + 1):
            dp[j] = 10010

        for i in range(1, n + 1):
            for j in range(0, amount + 1):
                if coins[i - 1] <= j:
                    dp[j] = min(dp[j], dp[j - coins[i - 1]] + 1)

                

        return -1 if dp[amount] > amount else dp[amount]

518 零钱兑换

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        # f(i,j) 考虑前 i 个硬币,凑出 j 有多少种方案?
        # f(i-1, j) + f(i, j-coins[i-1]) 完全背包

        n = len(coins)
        dp = [0] * (amount + 1)
        dp[0] = 1

        for i in range(1, n + 1):
            for j in range(coins[i - 1], amount + 1):
                dp[j] += dp[j - coins[i - 1]]
        return dp[amount]

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

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

相关文章

在线尺码计算

在线衣服尺码计算 尺码不确定的话&#xff0c;可以填写身高、体重生成可以参考的尺码还是不错的 工具简介 选购时请综合参考尺码表中的各项参数&#xff0c;这有助您选择到更好的尺码。 该尺码计算工具仅供参考&#xff0c;测量脚时请注意用适当力度轻踩水平面上。因测量方法不…

Tomcat和Servlet

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Tomcat是什么&#xff1f;1.1下载&#xff1a;1.2 tomcat是什么1.3启动服务器&#xff1a; 二.部署三、Servlet3.1创建项目3.2引入依赖pom.xml的所有代码 3…

electron——查看electron的版本(代码片段)

electron——查看electron的版本(代码片段)1.使用命令行&#xff1a; npm ls electron 操作如下&#xff1a; 2.在软件内使用代码&#xff0c;如下&#xff1a; console.log(process) console.log(process.versions.electron) process 里包含很多信息&#xff1a; process详…

Python装饰器的专业解释

装饰器&#xff0c;其实是用到了闭包的原理来进行操作的。 单个装饰器&#xff1a; 以下是一个简单的例子&#xff1a; def outer(func):print("OUTER enter ...")def wrapper(*args, **kwargs):print("调用之前......")result func(*args, **kwargs)p…

4.31 构建onnx结构模型-Tile

前言 构建onnx方式通常有两种&#xff1a; 1、通过代码转换成onnx结构&#xff0c;比如pytorch —> onnx 2、通过onnx 自定义结点&#xff0c;图&#xff0c;生成onnx结构 本文主要是简单学习和使用两种不同onnx结构&#xff0c; 下面以 Tile 结点进行分析 方式 方法一…

用Xshell连接虚拟机的Ubuntu20.04系统记录。虚拟机Ubuntu无法上网。本机能ping通虚拟机,反之不能。互ping不通

先别急着操作&#xff0c;看完再试。 如果是&#xff1a;本机能ping通虚拟机&#xff0c;反之不能。慢慢看到第8条。 如果是&#xff1a;虚拟机不能上网&#xff08;互ping不通&#xff09;&#xff0c;往下一直看。 系统是刚装的&#xff0c;安装步骤&#xff1a;VMware虚拟机…

DevOps系列 之 Python与Java互相调用的案例

Python和Java是两种非常流行的编程语言。Python是一种解释型语言&#xff0c;而Java则是一种编译型语言。两者都有广泛的应用&#xff0c;尤其是在测试领域。在本文中&#xff0c;我们将讨论如何使用Python测试Java源代码&#xff0c;Java如何调用Python脚本。 单元测试 单元…

redis的基本使用

一、 Redis简介 Redis是一个基于内存的 key-value 结构数据库。Redis是一款采用key-value数据存储格式的内存级NoSQL数据库&#xff0c;重点关注数据存储格式&#xff0c;是key-value格式&#xff0c;也就是键值对的存储形式。与MySQL数据库不同&#xff0c;MySQL数据库有表、…

WEB 3D技术 three.js 雾 基础使用讲解

本文 我们说一下 雾 在three.js中有一个 Fog类 它可以创建线性雾的一个效果 她就是模仿现实世界中 雾的一个效果 你看到远处物体会组件模糊 直到完全被雾掩盖 在 three.js 中 有两种雾的形式 一种是线性的 一种是指数的 个人觉得 线性的会看着自然一些 他是 从相机位置开始 雾…

Unity坦克大战开发全流程——开始场景——音效数据逻辑

开始场景——音效数据逻辑 从这里开始到后面的三小节我们都将干一件很重要的事——数据存储&#xff0c;只有实现了数据存储才能在再次进入游戏时保持游戏数据不被丢失。 类图分析&#xff1a;数据管理类是一个大类&#xff0c;它其中关联了两个类&#xff08;这两个类都是数据…

2023年终总结 —— 我和CSDN相遇的第一年之“技术学习和个人成长的回顾与展望”

​ ​ &#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 &#x1f38a;对2023的总结与回顾&#x1f38a; &#x1f3c5;获奖记录 &#x1f4da;学…

test mock-03-wiremock 模拟 HTTP 服务的开源工具 flexible and open source API mocking

拓展阅读 test 之 jmockit-01-overview jmockit-01-test 之 jmockit 入门使用案例 mockito-01-overview mockito 简介及入门使用 PowerMock Mock Server ChaosBlade-01-测试混沌工程平台整体介绍 jvm-sandbox 入门简介 wiremock WireMock是一个流行的开源工具&#xf…

蚂蚁实习一面面经

蚂蚁实习一面面经 希望可以帮助到大家 tcp建立连接为什么要三次握手&#xff1f; 三次握手的过程 注意&#xff1a;三次握手的最主要目的是保证连接是双工的&#xff0c;可靠更多的是通过重传机制来保证的 所谓三次握手&#xff0c;即建立TCP连接&#xff0c;需要客户端和…

Centos7部署Keepalived+lvs服务

IP规划&#xff1a; 服务器IP地址主服务器20.0.0.22/24从服务器20.0.0.24/24Web-120.0.0.26/24Web-220.0.0.27/24 一、主服务器安装部署keepalivedlvs服务 1、调整/proc响应参数 关闭Linux内核的重定向参数&#xff0c;因为LVS负载服务器和两个页面服务器需要共用一个VIP地…

力扣刷题记录(23)LeetCode:718、1143、1035

718. 最长重复子数组 要想到用一个二维数组dp去表示数组nums1和nums2的公共子数组的最大长度。其中二维数组的索引 i、j 分别表示nums1中[0,i-1]数组、nums2中[0,j-1]数组。如果满足nums1[i-1]nums2[j-1],那么dp[i][j]dp[i-1][j-1]1 class Solution { public:int findLength(v…

科技创新实验室数据管理优选:高效企业网盘推荐

科技创新实验室建设是国家加强科技创新基本能力建设的重要措施&#xff0c;企业网盘等高效办公工具的应用是保证科技创新实验室正常运行、提高科研项目团队合作效率的重要手段。 本文将介绍企业网盘Zoho WorkDrive提供的解决方案&#xff1a; 行业痛点1&#xff1a;分散的数据…

CentOS虚拟机硬盘管理

CentOS虚拟机硬盘管理 一、创建虚拟机时分配硬盘 创建虚拟机时&#xff0c;在下图这个页面需要重新选择一下硬盘&#xff0c;可以对硬盘进行配置。 默认自动分区 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e9ce72af3d934e75be95f7f86860e92b.png 选择确认分…

GitHub的2FA验证问题解决工具

文章目录 前言认识2FA开源工具使用&#xff1a;AuthenticatorPro获取AuthenticatorPro的安卓APK如何使用 参考文章 前言 打开GitHub跳出来这个提示&#xff0c;需要进行验证&#xff1a; 如何解决呢&#xff1f;方案有很多&#xff0c;我们可以使用开源的一个工具&#xff1a;…

微软开源,全平台通用:Shell 自动补全工具 | 开源日报 No.132

microsoft/inshellisense Stars: 7.6k License: MIT inshellisense 是一个为 Shell 提供 IDE 风格自动补全的工具。它是一个终端本地运行时自动完成&#xff0c;支持 600 多个命令行工具&#xff0c;并且可以在 Windows、Linux 和 macOS 上使用。主要功能包括安装后可通过运行…

QT 输入框输入限制 正则表达式限制 整理

在使用 输入数值时&#xff0c;经常遇到限制其范围的需要&#xff0c;比如角太阳高度角范围为[-90,90]&#xff0c;经度值范围[-180,180]&#xff0c;方位角范围[0,360]。Qt提供了QIntValidator和QDoubleValidator可以限定数值输入范围&#xff0c;如使用QIntValidator限制整数…