LeetCode 300/152/416/32 动态规划进阶题型总结(最长递增子序列→最长有效括号)

目录

一、题型总览

[二、题 1:最长递增子序列(LeetCode 300)](#二、题 1:最长递增子序列(LeetCode 300))

[1. 题目描述](#1. 题目描述)

[2. 核心理论](#2. 核心理论)

[3. 详细思路分析](#3. 详细思路分析)

(1)状态定义的推导

(2)初始化的原因

(3)状态转移的逻辑

[(4)优化思路(贪心 + 二分)的推导](#(4)优化思路(贪心 + 二分)的推导)

[4. 解法 1:一维 DP(O (n²),基础易理解)](#4. 解法 1:一维 DP(O (n²),基础易理解))

状态定义

初始化

状态转移

完整代码

[5. 解法 2:贪心 + 二分(O (nlogn),高效优化)](#5. 解法 2:贪心 + 二分(O (nlogn),高效优化))

核心思路

完整代码

[6. 易错点](#6. 易错点)

[7. 过程展示(示例nums=[10,9,2,5,3,7])](#7. 过程展示(示例nums=[10,9,2,5,3,7]))

[三、题 2:乘积最大子数组(LeetCode 152)](#三、题 2:乘积最大子数组(LeetCode 152))

[1. 题目描述](#1. 题目描述)

[2. 核心理论](#2. 核心理论)

[3. 详细思路分析](#3. 详细思路分析)

(1)状态定义的推导

(2)初始化的原因

(3)状态转移的逻辑

(4)优化思路(一维变量)的推导

[4. 解法 1:二维 DP(O (n²),基础易理解)](#4. 解法 1:二维 DP(O (n²),基础易理解))

状态定义

完整代码

[5. 解法 2:一维变量优化(O (n),高效)](#5. 解法 2:一维变量优化(O (n),高效))

状态定义

完整代码

[6. 易错点](#6. 易错点)

[7. 过程展示(示例nums=[-4,-3,-2])](#7. 过程展示(示例nums=[-4,-3,-2]))

[四、题 3:分割等和子集(LeetCode 416)](#四、题 3:分割等和子集(LeetCode 416))

[1. 题目描述](#1. 题目描述)

[2. 核心理论](#2. 核心理论)

[3. 详细思路分析](#3. 详细思路分析)

(1)问题转化的推导

(2)状态定义的推导

(3)初始化的原因

(4)状态转移的逻辑

(5)一维优化的推导

[4. 解法 1:二维 DP(O (n×target),基础)](#4. 解法 1:二维 DP(O (n×target),基础))

状态定义

完整代码

[5. 解法 2:一维 DP(倒序,O (target),优化)](#5. 解法 2:一维 DP(倒序,O (target),优化))

核心思路

完整代码

[6. 易错点](#6. 易错点)

[7. 过程展示(示例nums=[1,5,11,5],target=11)](#7. 过程展示(示例nums=[1,5,11,5],target=11))

[五、题 4:最长有效括号(LeetCode 32)](#五、题 4:最长有效括号(LeetCode 32))

[1. 题目描述](#1. 题目描述)

[2. 核心理论](#2. 核心理论)

[3. 详细思路分析](#3. 详细思路分析)

(1)状态定义的推导

(2)初始化的原因

[(3)状态转移的逻辑(仅处理s[i] = ')'的情况)](#(3)状态转移的逻辑(仅处理s[i] = ')'的情况))

[情况 1:s[i-1] = '('(直接配对)](#情况 1:s[i-1] = '('(直接配对))

[情况 2:s[i-1] = ')'(嵌套配对)](#情况 2:s[i-1] = ')'(嵌套配对))

(4)栈解法的推导

[4. 解法 1:动态规划(O (n),基础)](#4. 解法 1:动态规划(O (n),基础))

状态转移

完整代码

[5. 解法 2:栈解法(O (n),非 DP)](#5. 解法 2:栈解法(O (n),非 DP))

核心思路

完整代码

[6. 易错点](#6. 易错点)

[7. 过程展示(示例s=")()())")](#7. 过程展示(示例s=")()())"))

六、整体总结

[1. 核心共性](#1. 核心共性)

[2. 核心差异](#2. 核心差异)

[3. 解题技巧](#3. 解题技巧)


一、题型总览

本次总结覆盖 4 道动态规划核心进阶题,涵盖「子序列 / 子数组 / 子串」三类场景,每道题均提供两种核心解法(基础 DP / 优化 DP / 非 DP 解法),并拆解易错点、难点及核心逻辑:

题目 核心场景 解法 1(基础) 解法 2(优化 / 非 DP) 核心难点
最长递增子序列 非连续子序列 二维 / 一维 DP(O (n²)) 贪心 + 二分(O (nlogn)) dp [i] 定义(以 i 结尾)
乘积最大子数组 连续子数组 二维 DP(O (n²)) 一维变量优化(O (n)) 负数反转最大 / 最小乘积
分割等和子集 01 背包(可行性) 二维 DP(O (n×target)) 一维 DP(倒序,O (target)) 倒序遍历避免重复选
最长有效括号 连续子串 动态规划(O (n)) 栈解法(O (n)) 括号匹配的嵌套 + 拼接逻辑

二、题 1:最长递增子序列(LeetCode 300)

1. 题目描述

给一个整数数组nums,求最长严格递增子序列的长度(子序列非连续)。示例:nums=[10,9,2,5,3,7,101,18] → 输出 4([2,3,7,101])。

2. 核心理论

状态定义核心:dp[i] =nums[i]结尾的最长严格递增子序列长度必须以 i 结尾,而非前 i 个的全局最长)。

3. 详细思路分析

(1)状态定义的推导
  • 子序列的核心是 "非连续",要找最长递增子序列,首先要拆解问题规模:如果想知道 "以nums[i]结尾的最长递增子序列长度",只需要看nums[i]前面所有 比它小的元素nums[j](j < i),取dp[j] + 1的最大值(因为nums[i]可以接在nums[j]的子序列后面);
  • 若直接定义 "前 i 个元素的最长递增子序列长度",会无法处理 "非连续" 的特性(比如前 i 个的最长子序列可能不包含nums[i],无法推导后续状态),因此 "以 i 结尾" 是更合理的拆分方式。
(2)初始化的原因
  • 每个元素自身可以构成一个长度为 1 的递增子序列(哪怕前面没有比它小的元素),因此dp[i]初始值必须为 1,而非默认的 0(若初始为 0,会导致单个元素的子序列长度被错误计算)。
(3)状态转移的逻辑
  • 遍历i从 1 到 n-1(因为要对比前面的元素,0的情况已经初始化),对每个i,遍历j从 0 到 i-1:
    • nums[i] > nums[j]:说明nums[i]可以接在以nums[j]结尾的子序列后,此时dp[i] = max(dp[i], dp[j] + 1);
    • nums[i] ≤ nums[j]:说明无法接在nums[j]后,dp[i]保持原值;
  • 最终需要维护一个全局maxLen,因为最长子序列不一定以最后一个元素结尾(比如示例中最长子序列结尾是 101,而非 18)。
(4)优化思路(贪心 + 二分)的推导
  • 基础 DP 的时间复杂度是 O (n²),瓶颈在于 "遍历 j 找所有比nums[i]小的元素";
  • 贪心思路:要让递增子序列尽可能长,需要让子序列的结尾元素尽可能小(比如[2,5][2,7]更容易接后续元素),因此维护tails数组记录 "长度为 k+1 的递增子序列的最小结尾元素";
  • 二分的作用:遍历nums时,用二分快速找到nums[i]tails中的位置,替换或追加,从而将时间复杂度降到 O (nlogn)。

4. 解法 1:一维 DP(O (n²),基础易理解)

状态定义

dp[i]:以nums[i]结尾的最长严格递增子序列长度。

初始化

dp[i] = 1(每个元素自身构成长度为 1 的子序列)。

状态转移
java 复制代码
for (int i = 1; i < n; i++) {
    for (int j = 0; j < i; j++) {
        if (nums[i] > nums[j]) {
            dp[i] = Math.max(dp[i], dp[j] + 1);
        }
    }
    maxLen = Math.max(maxLen, dp[i]);
}
完整代码
java 复制代码
class Solution {
    public int lengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int n = nums.length;
        int[] dp = new int[n];
        Arrays.fill(dp, 1); // 初始化每个dp[i]=1
        int maxLen = 1;

        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            maxLen = Math.max(maxLen, dp[i]);
        }
        return maxLen;
    }
}

5. 解法 2:贪心 + 二分(O (nlogn),高效优化)

核心思路

维护tails数组:tails[i] = 长度为i+1的递增子序列的最小结尾元素(贪心选最小结尾,为后续留更大空间)。

完整代码
java 复制代码
class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] tails = new int[nums.length];
        int len = 0; // tails的有效长度
        for (int num : nums) {
            // 二分找第一个≥num的位置
            int left = 0, right = len;
            while (left < right) {
                int mid = left + (right - left) / 2;
                if (tails[mid] < num) left = mid + 1;
                else right = mid;
            }
            tails[left] = num;
            if (left == len) len++; // 插入到末尾,长度+1
        }
        return len;
    }
}

6. 易错点

  • dp[i]未初始化为 1(默认 0 导致结果错误);
  • 直接返回dp[n-1](忽略 "最长子序列不一定以最后一个元素结尾");
  • 贪心解法中二分边界错误(比如right=len-1导致漏解)。

7. 过程展示(示例nums=[10,9,2,5,3,7]

i nums[i] dp[i] tails 数组(解法 2)
0 10 1 [10]
1 9 1 [9]
2 2 1 [2]
3 5 2 [2,5]
4 3 2 [2,3]
5 7 3 [2,3,7]

三、题 2:乘积最大子数组(LeetCode 152)

1. 题目描述

给整数数组nums,求连续 子数组的最大乘积。示例:nums=[2,3,-2,4] → 输出 6([2,3]);nums=[-2,0,-1] → 输出 0。

2. 核心理论

乘积的特殊性:负数 × 负数 = 正数,需同时维护「以 i 结尾的最大乘积」和「最小乘积」(最小乘积可能是负数,乘下一个负数变最大)。

3. 详细思路分析

(1)状态定义的推导
  • 子数组的核心是 "连续",因此状态定义需绑定 "以 i 结尾":dpMax[i] = 以nums[i]结尾的最大乘积,dpMin[i] = 以nums[i]结尾的最小乘积;
  • 若只维护dpMax,会漏掉 "负数 × 负数 = 正数" 的情况(比如nums=[-4,-3,-2]dpMax[1]=12,若没有dpMin,无法推导dpMax[2])。
(2)初始化的原因
  • 连续子数组至少包含一个元素,因此dpMax[0] = dpMin[0] = nums[0](第一个元素的最大 / 最小乘积都是自身);
  • 全局result初始化为nums[0],因为至少有一个元素,最大乘积不会小于第一个元素。
(3)状态转移的逻辑

对每个i ≥ 1,以nums[i]结尾的乘积有 3 种可能:

  1. 只选nums[i](前面的乘积为负,单独选更优);
  2. dpMax[i-1] × nums[i](前面的最大乘积 × 当前元素);
  3. dpMin[i-1] × nums[i](前面的最小乘积 × 当前元素,负数 × 负数可能变最大);因此:
  • dpMax[i] = max(nums[i], dpMax[i-1]×nums[i], dpMin[i-1]×nums[i])
  • dpMin[i] = min(nums[i], dpMax[i-1]×nums[i], dpMin[i-1]×nums[i])
(4)优化思路(一维变量)的推导
  • 基础二维 DP 需要 O (n) 空间存储dpMaxdpMin,但观察到dpMax[i]/dpMin[i]仅依赖前一个状态dpMax[i-1]/dpMin[i-1],因此可用两个变量preMax/preMin替代数组,将空间复杂度降到 O (1);
  • 注意:更新preMin时需要用到原始的preMax,因此需先临时保存preMax,避免覆盖。

4. 解法 1:二维 DP(O (n²),基础易理解)

状态定义
  • dpMax[i][j]:子数组nums[i...j]的最大乘积;
  • dpMin[i][j]:子数组nums[i...j]的最小乘积。
完整代码
java 复制代码
class Solution {
    public int maxProduct(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int n = nums.length;
        int[][] dpMax = new int[n][n];
        int[][] dpMin = new int[n][n];
        int max = nums[0];

        // 初始化:子数组长度为1时,最大/最小都是自身
        for (int i = 0; i < n; i++) {
            dpMax[i][i] = nums[i];
            dpMin[i][i] = nums[i];
            max = Math.max(max, nums[i]);
        }

        // 遍历子数组长度(从2到n)
        for (int len = 2; len <= n; len++) {
            for (int i = 0; i + len <= n; i++) {
                int j = i + len - 1;
                int val1 = dpMax[i][j-1] * nums[j];
                int val2 = dpMin[i][j-1] * nums[j];
                dpMax[i][j] = Math.max(nums[j], Math.max(val1, val2));
                dpMin[i][j] = Math.min(nums[j], Math.min(val1, val2));
                max = Math.max(max, dpMax[i][j]);
            }
        }
        return max;
    }
}

5. 解法 2:一维变量优化(O (n),高效)

状态定义
  • preMax:以nums[i-1]结尾的最大乘积;
  • preMin:以nums[i-1]结尾的最小乘积。
完整代码
java 复制代码
class Solution {
    public int maxProduct(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int preMax = nums[0], preMin = nums[0], result = nums[0];

        for (int i = 1; i < nums.length; i++) {
            int cur = nums[i];
            // 临时保存preMax,避免更新后被覆盖
            int tempMax = preMax;
            preMax = Math.max(cur, Math.max(tempMax * cur, preMin * cur));
            preMin = Math.min(cur, Math.min(tempMax * cur, preMin * cur));
            result = Math.max(result, preMax);
        }
        return result;
    }
}

6. 易错点

  • 仅维护最大乘积(忽略负数反转的情况);
  • 初始化用Integer.MAX_VALUE(导致溢出);
  • 未临时保存preMax(更新preMin时用了已修改的preMax)。

7. 过程展示(示例nums=[-4,-3,-2]

i nums[i] preMax preMin result
0 -4 -4 -4 -4
1 -3 12 -3 12
2 -2 6 -24 12

四、题 3:分割等和子集(LeetCode 416)

1. 题目描述

给正整数数组nums,判断能否分割为两个子集,使子集和相等。示例:nums=[1,5,11,5] → 输出 true;nums=[1,2,3,5] → 输出 false。

2. 核心理论

转化为 01 背包可行性问题:总和s为偶数时,判断能否选若干数凑出s/2(每个数只能选 1 次)。

3. 详细思路分析

(1)问题转化的推导
  • 分割为两个和相等的子集 → 总和s必须是偶数(否则无法平分),目标和target = s/2
  • 问题等价于 "从数组中选若干数(每个数只能选 1 次),使和为 target"------ 这是典型的 01 背包 "可行性判断" 问题(区别于 "最大价值""方案数")。
(2)状态定义的推导
  • 01 背包的核心是 "选 / 不选第 i 个物品",因此状态定义为dp[i][j]:前i个数能否凑出和为j
  • 维度拆解:i表示 "前 i 个数"(物品维度),j表示 "目标和"(容量维度)。
(3)初始化的原因
  • dp[i][0] = true:前 i 个数凑和为 0,只需不选任何数,一定可行(背包容量为 0 时,空集永远满足);
  • dp[0][j] = false(j > 0):没有数可选时,无法凑出大于 0 的和。
(4)状态转移的逻辑

对第i个数(nums[i-1]),分两种情况:

  1. 不选:dp[i][j] = dp[i-1][j](前 i-1 个数能凑 j,前 i 个数也能);
  2. 选:若j ≥ nums[i-1],则dp[i][j] = dp[i-1][j - nums[i-1]](前 i-1 个数能凑j - nums[i-1],加上当前数就凑 j);最终dp[i][j] = 不选 || 选(只要有一个可行,结果就为 true)。
(5)一维优化的推导
  • 二维 DP 的空间复杂度是 O (n×target),观察到dp[i][j]仅依赖dp[i-1][...](上一行),因此可压缩为一维数组dp[j]
  • 01 背包的关键:一维数组需倒序遍历容量(从 target 到 nums [i]),避免同一数被重复选(正序遍历会变成 "完全背包",数可重复选)。

4. 解法 1:二维 DP(O (n×target),基础)

状态定义

dp[i][j]:前i个数能否凑出和为j

完整代码
java 复制代码
class Solution {
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for (int num : nums) sum += num;
        if (sum % 2 != 0) return false;
        int target = sum / 2;
        int n = nums.length;
        boolean[][] dp = new boolean[n + 1][target + 1];

        // 初始化:前i个数凑0一定可行
        for (int i = 0; i <= n; i++) dp[i][0] = true;

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= target; j++) {
                if (j >= nums[i-1]) {
                    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][target];
    }
}

5. 解法 2:一维 DP(倒序,O (target),优化)

核心思路

倒序遍历容量,避免同一数被重复选(01 背包核心)。

完整代码
java 复制代码
class Solution {
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for (int num : nums) sum += num;
        if (sum % 2 != 0) return false;
        int target = sum / 2;
        boolean[] dp = new boolean[target + 1];
        dp[0] = true; // 凑0一定可行

        for (int num : nums) {
            // 倒序遍历:从target到num,避免重复选
            for (int j = target; j >= num; j--) {
                dp[j] = dp[j] || dp[j - num];
            }
            if (dp[target]) return true; // 提前剪枝
        }
        return dp[target];
    }
}

6. 易错点

  • 未判断总和奇偶性(直接 DP 导致无效计算);
  • 一维 DP 正序遍历(变成完全背包,重复选数);
  • 二维 DP 遗漏j < nums[i-1]时的状态继承。

7. 过程展示(示例nums=[1,5,11,5],target=11)

遍历数字 dp 数组(一维)
初始 [T,F,F,...F]
1 [T,T,F,...F]
5 [T,T,F,F,F,T,T,...F]
11 [T,T,F,F,F,T,T,...T]

五、题 4:最长有效括号(LeetCode 32)

1. 题目描述

给只含'('')'的字符串s,求最长有效括号子串的长度(子串连续)。示例:s=")()())" → 输出 4;s="(()" → 输出 2。

2. 核心理论

状态定义核心:dp[i] = 以s[i]结尾的最长有效括号长度(以 i 结尾'('结尾时 dp [i]=0)。

3. 详细思路分析

(1)状态定义的推导
  • 子串的核心是 "连续",因此状态需绑定 "以 i 结尾":只有知道以i结尾的有效长度,才能推导以i+1结尾的长度;
  • 有效括号的特性:必须以')'结尾(以'('结尾的子串永远无法闭合,因此dp[i]=0)。
(2)初始化的原因
  • dp数组初始值为 0:未处理时,所有位置的有效长度默认 0;
  • 全局maxLen初始值为 0:初始时无有效子串。
(3)状态转移的逻辑(仅处理s[i] = ')'的情况)
情况 1:s[i-1] = '('(直接配对)
  • s[i]s[i-1]组成"()",长度为 2;
  • i ≥ 2,还需加上以i-2结尾的有效长度(比如"()()"i=3时需加上i=1的长度 2);
  • 公式:dp[i] = (i ≥ 2 ? dp[i-2] : 0) + 2
情况 2:s[i-1] = ')'(嵌套配对)
  • 先找到以i-1结尾的有效子串的 "前一个字符":pos = i - dp[i-1] - 1
  • pos ≥ 0s[pos] = '(',说明s[i]能和s[pos]配对,长度为dp[i-1] + 2
  • pos ≥ 1,还需加上以pos-1结尾的有效长度(比如"()(())"i=5时需加上i=1的长度 2);
  • 公式:dp[i] = dp[i-1] + 2 + (pos-1 ≥ 0 ? dp[pos-1] : 0)
(4)栈解法的推导
  • DP 解法依赖状态推导,栈解法更直观:用栈记录 "最后一个无效括号的下标";
  • 遇到'('压入下标,遇到')'弹出栈顶(匹配'(');
  • 若栈空,压入当前下标(更新无效下标);否则,有效长度 = 当前下标 - 栈顶下标。

4. 解法 1:动态规划(O (n),基础)

状态转移
  • 情况 1:s[i]=')'s[i-1]='('dp[i] = dp[i-2] + 2
  • 情况 2:s[i]=')'s[i-1]=')' → 若s[i-dp[i-1]-1]='(',则dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2]
完整代码

java

运行

java 复制代码
class Solution {
    public int longestValidParentheses(String s) {
        int n = s.length();
        if (n < 2) return 0;
        int[] dp = new int[n];
        int maxLen = 0;

        for (int i = 1; i < n; i++) {
            if (s.charAt(i) == ')') {
                // 情况1:前一个是'('
                if (s.charAt(i-1) == '(') {
                    dp[i] = (i >= 2 ? dp[i-2] : 0) + 2;
                }
                // 情况2:前一个是')',找更前面的'('
                else if (i - dp[i-1] > 0 && s.charAt(i - dp[i-1] - 1) == '(') {
                    dp[i] = dp[i-1] + 2 + (i - dp[i-1] - 2 >= 0 ? dp[i - dp[i-1] - 2] : 0);
                }
                maxLen = Math.max(maxLen, dp[i]);
            }
        }
        return maxLen;
    }
}

5. 解法 2:栈解法(O (n),非 DP)

核心思路

用栈记录 "最后一个无效括号的下标",有效长度 = 当前下标 - 栈顶下标。

完整代码
java 复制代码
class Solution {
    public int longestValidParentheses(String s) {
        Deque<Integer> stack = new LinkedList<>();
        stack.push(-1); // 初始无效下标
        int maxLen = 0;

        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '(') {
                stack.push(i); // 压入'('的下标
            } else {
                stack.pop(); // 弹出栈顶(匹配'(')
                if (stack.isEmpty()) {
                    stack.push(i); // 无匹配,更新无效下标
                } else {
                    maxLen = Math.max(maxLen, i - stack.peek());
                }
            }
        }
        return maxLen;
    }
}

6. 易错点

  • dp[i]定义错误(未关注 "以 i 结尾",误算全局最长);
  • 下标越界(未判断i-dp[i-1]-1 >=0);
  • 处理'('结尾的情况(实际无需处理,dp [i]=0)。

7. 过程展示(示例s=")()())"

i s[i] dp[i] maxLen
0 ')' 0 0
1 '(' 0 0
2 ')' 2 2
3 '(' 0 2
4 ')' 4 4
5 ')' 0 4

六、整体总结

1. 核心共性

  • 状态定义:多以 "以 i 结尾" 为核心(子序列 / 子数组 / 子串的 DP 通用技巧);
  • 初始化:基准状态(如dp[0]=1/dp[0]=true)是 DP 的基础;
  • 边界处理:下标越界、特殊值(如负数、空串)需优先判断。

2. 核心差异

场景 关键逻辑
非连续子序列 遍历前面所有元素,取最优解
连续子数组 / 串 仅依赖前一个 / 前若干个状态
背包问题 遍历顺序决定 "选 1 次 / 选多次"

3. 解题技巧

  • 先理解 "基础 DP 解法"(二维 / 暴力),再优化(一维 / 贪心 / 非 DP);
  • 遇到 "乘积 / 括号" 等特殊约束,需补充辅助状态(如最小乘积、栈记录下标);
  • 状态定义的核心是 "缩小问题规模"(以 i 结尾→只关注 i 的局部,推导全局)。

相关推荐
天赐学c语言2 小时前
12.18 - 有效的括号 && C语言中static的作用
数据结构·c++·算法·leecode
2401_876221342 小时前
数据结构-绪论
数据结构
季远迩2 小时前
LeetCode 热题 100 Python3易懂题解(更新中)
算法·leetcode·哈希算法
CoovallyAIHub2 小时前
从“模仿”到“进化”!华科&小米开源MindDrive:在线强化学习重塑「语言-动作」闭环驾驶
深度学习·算法·计算机视觉
别动哪条鱼2 小时前
SDL 函数对各对象缓冲区的影响
网络·数据结构·ffmpeg
xie_pin_an2 小时前
C 语言排序算法全解析:从原理到实战,附性能对比
c语言·算法·排序算法
CoovallyAIHub2 小时前
SAM 真的开始「分割一切」,从图像到声音,Meta 开源 SAM Audio
深度学习·算法·计算机视觉
Dream it possible!2 小时前
LeetCode 面试经典 150_回溯_组合(99_77_C++_中等)
c++·leetcode·面试·回溯
三斗米2 小时前
从思维链到思维树:一步步解锁大语言模型的推理能力
算法