面试算法高频08-动态规划-03
练习题
题目描述
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组 nums
,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
示例 1:
输入:nums = [1,2,3,1]
输出:4
解释:偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3),偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入:nums = [2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋(金额 = 2),偷窃 3 号房屋(金额 = 9),接着偷窃 5 号房屋(金额 = 1),偷窃到的最高金额 = 2 + 9 + 1 = 12 。
最优解(动态规划 + 空间优化)
利用动态规划思想,通过滚动变量优化空间复杂度至 (O(1))。
思路:
定义两个变量 first
和 second
,分别表示偷到前前一间房屋和前一间房屋的最大金额。对于当前房屋,有两种选择:
- 偷当前房屋:则总金额为
first + 当前房屋金额
。 - 不偷当前房屋:则总金额为
second
。
取两者最大值更新状态,逐步迭代。
代码:
class Solution: def rob(self, nums: List[int]) -> int: if not nums: return 0 if len(nums) == 1: return nums[0] first, second = nums[0], max(nums[0], nums[1]) for i in range(2, len(nums)): first, second = second, max(second, first + nums[i]) return second
复杂度分析:
- 时间复杂度:(O(n)),其中 (n) 是房屋数量,需遍历数组一次。
- 空间复杂度:(O(1)),仅用两个变量存储状态。
答案解析:
- 初始化
first
为第一间房屋金额,second
为前两间房屋的较大值。 - 从第三间房屋开始迭代,每次更新
first
和second
,first
代表前前一间的最大值,second
代表前一间的最大值。 - 最终
second
即为偷到最后一间房屋时的最大金额,返回该值。
题目:完全平方数
给定正整数 ( n ),找到若干个完全平方数(比如 ( 1, 4, 9, 16, \dots ))使得它们的和等于 ( n ),要求组成和的完全平方数的个数最少。
解法:动态规划
思路:
定义 ( dp[i] ) 表示组成 ( i ) 的最少完全平方数个数。对于每个 ( i ),遍历小于 ( i ) 的完全平方数 ( j^2 ),通过状态转移方程 ( dp[i] = \min(dp[i], dp[i - j^2] + 1) ) 计算最小值。
代码:
import mathdef numSquares(n):dp = [float('inf')] * (n + 1)dp[0] = 0for i in range(1, n + 1):max_j = int(math.sqrt(i))for j in range(1, max_j + 1):if i >= j * j:dp[i] = min(dp[i], dp[i - j * j] + 1)return dp[n]
解释:
- 初始化 ( dp ) 数组,
dp[0] = 0
表示 ( 0 ) 不需要任何完全平方数。 - 遍历 ( i ) 从 ( 1 ) 到 ( n ),对于每个 ( i ),遍历 ( j )(( j^2 \leq i ))。
- 通过状态转移方程更新 ( dp[i] ),取最小值。
- 最终 ( dp[n] ) 即为组成 ( n ) 的最少完全平方数个数。
时间复杂度:( O(n\sqrt{n}) ),遍历 ( n ) 次,每次遍历 ( \sqrt{n} ) 次。
空间复杂度:( O(n) ),存储 ( dp ) 数组。
此方法通过动态规划高效地计算出最少完全平方数个数,确保了算法的正确性和效率。
题目描述
给你两个单词 word1
和 word2
,请返回将 word1
转换成 word2
所使用的最少操作数。你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符
最优解(Python)
from typing import Listclass Solution:def minDistance(self, word1: str, word2: str) -> int:m, n = len(word1), len(word2)# 创建二维数组,dp[i][j]表示将 word1 的前 i 个字符转换为 word2 的前 j 个字符的最少操作数dp = [[0] * (n + 1) for _ in range(m + 1)]# 初始化边界条件for i in range(m + 1):dp[i][0] = i # word1 前 i 个字符转换为空字符串,需要删除 i 个字符for j in range(n + 1):dp[0][j] = j # 空字符串转换为 word2 前 j 个字符,需要插入 j 个字符# 填充 dp 数组for i in range(1, m + 1):for j in range(1, n + 1):if word1[i - 1] == word2[j - 1]:# 当前字符相同,不需要操作,直接取左上角的值dp[i][j] = dp[i - 1][j - 1]else:# 取插入、删除、替换三种操作的最小值,然后加 1(因为进行了一次操作)dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1])return dp[m][n]
最优解分析
-
动态规划思路:
- 定义
dp[i][j]
表示将word1
的前i
个字符转换为word2
的前j
个字符的最少操作数。 - 边界条件:
- 若
word1
为空字符串(i = 0
),则需要插入j
个字符才能转换为word2
的前j
个字符,即dp[0][j] = j
。 - 若
word2
为空字符串(j = 0
),则需要删除i
个字符才能将word1
的前i
个字符转换为空字符串,即dp[i][0] = i
。
- 若
- 状态转移方程:
- 当
word1[i - 1] == word2[j - 1]
时,当前字符相同,不需要进行插入、删除或替换操作,所以dp[i][j] = dp[i - 1][j - 1]
。 - 当
word1[i - 1] != word2[j - 1]
时,有三种操作选择:- 插入:将
word1
的前i
个字符转换为word2
的前j - 1
个字符(dp[i][j - 1]
),再插入一个字符,操作数为dp[i][j - 1] + 1
。 - 删除:将
word1
的前i - 1
个字符转换为word2
的前j
个字符(dp[i - 1][j]
),再删除一个字符,操作数为dp[i - 1][j] + 1
。 - 替换:将
word1
的前i - 1
个字符转换为word2
的前j - 1
个字符(dp[i - 1][j - 1]
),再替换一个字符,操作数为dp[i - 1][j - 1] + 1
。
取这三种操作数的最小值,即dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1])
。
- 插入:将
- 当
- 定义
-
复杂度分析:
- 时间复杂度:( O(m \times n) ),其中 ( m ) 和 ( n ) 分别是
word1
和word2
的长度,需要遍历一个 ( (m + 1) \times (n + 1) ) 的二维数组。 - 空间复杂度:( O(m \times n) ),使用了一个 ( (m + 1) \times (n + 1) ) 的二维数组来存储中间状态。
- 时间复杂度:( O(m \times n) ),其中 ( m ) 和 ( n ) 分别是
编辑距离(最少操作数转换单词)
题目描述
给定两个单词 word1
和 word2
,计算将 word1
转换成 word2
所需的最少操作数。允许的操作有三种:
- 插入一个字符
- 删除一个字符
- 替换一个字符
最优解:动态规划(Python实现)
from typing import Listclass Solution:def minDistance(self, word1: str, word2: str) -> int:m, n = len(word1), len(word2)# 创建二维数组 dp,其中 dp[i][j] 表示将 word1 的前 i 个字符转换为 word2 的前 j 个字符的最少操作数dp = [[0] * (n + 1) for _ in range(m + 1)]# 初始化边界条件:当其中一个单词为空时的操作数for i in range(m + 1):dp[i][0] = i # 删除 word1 前 i 个字符(全部删除,操作数为 i)for j in range(n + 1):dp[0][j] = j # 插入 word2 前 j 个字符(全部插入,操作数为 j)# 填充 dp 数组for i in range(1, m + 1):for j in range(1, n + 1):if word1[i-1] == word2[j-1]:# 当前字符相同,无需操作,直接继承左上角的结果dp[i][j] = dp[i-1][j-1]else:# 当前字符不同,选择三种操作中的最小值并加 1(当前操作)dp[i][j] = 1 + min(dp[i-1][j], # 删除 word1 的第 i 个字符(对应 word1 前 i-1 转换为 word2 前 j)dp[i][j-1], # 插入 word2 的第 j 个字符(对应 word1 前 i 转换为 word2 前 j-1)dp[i-1][j-1] # 替换 word1 的第 i 个字符为 word2 的第 j 个字符(对应前 i-1 和 j-1 转换))return dp[m][n] # 返回最终结果,即两个完整单词的最少操作数
最优解分析
1. 动态规划思路
编辑距离问题是典型的动态规划问题,核心是通过子问题的解推导原问题的解。
- 状态定义:
设dp[i][j]
表示将word1
的前i
个字符转换为word2
的前j
个字符所需的最少操作数。 - 状态转移:
- 若当前字符相同(
word1[i-1] == word2[j-1]
),则无需操作,直接继承左上角的状态dp[i-1][j-1]
。 - 若当前字符不同,则有三种操作选择,取其中最小值并加 1(当前操作):
- 删除:删除
word1
的第i
个字符,操作数为dp[i-1][j] + 1
。 - 插入:在
word1
中插入word2
的第j
个字符,操作数为dp[i][j-1] + 1
。 - 替换:将
word1
的第i
个字符替换为word2
的第j
个字符,操作数为dp[i-1][j-1] + 1
。
- 删除:删除
- 若当前字符相同(
2. 边界条件
- 当
word1
为空(i=0
)时,需要插入word2
的前j
个字符,操作数为j
。 - 当
word2
为空(j=0
)时,需要删除word1
的前i
个字符,操作数为i
。
3. 复杂度分析
- 时间复杂度:( O(m \times n) ),其中
m
和n
分别为两个单词的长度。需要遍历一个 ( (m+1) \times (n+1) ) 的二维数组。 - 空间复杂度:( O(m \times n) ),使用二维数组存储中间状态。若优化空间,可压缩为一维数组(每次仅保留前一行的状态),但此处采用直观的二维数组解法,便于理解。
4. 示例推导
以 word1 = "horse", word2 = "ros"
为例:
- 初始化边界:第一行和第一列分别为
0,1,2,3
和0,1,2,3,4,5
(对应插入或删除操作)。 - 填充过程中,当字符相同时(如
h
vsr
不同,o
vso
相同),根据状态转移方程逐步计算每个dp[i][j]
。 - 最终
dp[5][3]
即为结果3
(实际最少操作:horse
→rorse
(替换 h→r)→rose
(删除 r)→ros
(删除 e),共 3 步)。
总结
编辑距离问题通过动态规划将复杂的字符串转换问题分解为子问题,利用状态转移方程高效求解。关键在于正确定义状态和转移逻辑,边界条件的处理也至关重要。该解法是此类问题的经典解法,时间和空间复杂度均为多项式级别,适用于大多数实际场景。
题目描述
给定一个非负整数数组 nums
,你最初位于数组的 第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步到下标 1,然后跳 3 步到达最后一个下标。
示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置(值为 0),无法继续跳跃到最后一个下标。
最优解(贪心算法)
通过维护当前能到达的最远位置,遍历数组时不断更新该位置,若在遍历过程中最远位置覆盖最后一个下标,则返回 True
;若当前位置超过最远位置,说明无法继续跳跃,返回 False
。
Python代码
from typing import Listclass Solution:def canJump(self, nums: List[int]) -> bool:n = len(nums)max_reach = 0 # 初始化当前能到达的最远位置for i in range(n):# 如果当前位置在可到达范围内,则尝试更新最远位置if i <= max_reach:max_reach = max(max_reach, i + nums[i])# 提前判断是否已到达或超过最后一个下标,优化性能if max_reach >= n - 1:return Trueelse:# 当前位置超出可到达范围,无法继续跳跃break# 遍历结束后,若最远位置仍未到达最后一个下标,返回Falsereturn max_reach >= n - 1
最优解分析
思路解析
-
贪心策略:
每次遍历到位置i
时,若i
在当前最远可达位置max_reach
内,则更新max_reach
为i + nums[i]
(即从i
出发能到达的最远位置)和当前max_reach
中的较大值。- 若
max_reach
在遍历过程中已覆盖最后一个下标(n-1
),则直接返回True
,无需继续遍历。 - 若某一位置
i
超出max_reach
,说明后续位置无法到达,直接跳出循环并返回False
。
- 若
-
边界处理:
- 当数组长度为
0
或1
时,直接返回True
(空数组题目保证输入合法,长度为 1 时无需跳跃即可到达)。 - 遍历过程中,若
i
超过max_reach
,说明中间存在无法跨越的“断层”,直接终止遍历。
- 当数组长度为
复杂度分析
- 时间复杂度:( O(n) ),其中 ( n ) 是数组
nums
的长度。仅需遍历数组一次,每个元素处理时间为常数。 - 空间复杂度:( O(1) ),仅使用常数级额外空间(
max_reach
和循环变量)。
示例推导
以示例 2 nums = [3,2,1,0,4]
为例:
- 初始
max_reach = 0
。 i=0
:0 <= 0
,更新max_reach = max(0, 0+3=3)
,此时max_reach=3
,未达最后下标(4)。i=1
:1 <= 3
,更新max_reach = max(3, 1+2=3)
,仍为 3。i=2
:2 <= 3
,更新max_reach = max(3, 2+1=3)
,仍为 3。i=3
:3 <= 3
,更新max_reach = max(3, 3+0=3)
,仍为 3。i=4
:4 > 3
,跳出循环,返回False
,符合预期。
关键点
- 贪心的核心:每次尽可能扩展最远可达范围,避免重复计算中间状态。
- 提前终止:一旦最远可达范围覆盖最后一个下标,立即返回
True
,优化最坏情况下的性能。
该解法通过线性遍历和常数空间,高效解决了跳跃游戏问题,是此类问题的经典贪心解法。
题目描述
给定一个非负整数数组 nums
,你最初位于数组的 第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。
最优解(贪心算法)
通过维护当前能到达的最远位置,遍历数组时动态更新该位置,若在遍历过程中最远位置覆盖最后一个下标,则直接返回 True
;若当前位置超出最远可达范围,说明无法继续跳跃,返回 False
。
Python代码
from typing import Listclass Solution:def canJump(self, nums: List[int]) -> bool:n = len(nums)max_reach = 0 # 当前能到达的最远下标for i in range(n):# 如果当前位置在可达范围内,则尝试更新最远可达位置if i <= max_reach:max_reach = max(max_reach, i + nums[i])# 提前判断是否已到达终点,优化性能if max_reach >= n - 1:return Trueelse:# 当前位置不可达,后续位置也无法到达break# 遍历结束后,检查最远可达位置是否覆盖终点return max_reach >= n - 1
最优解分析
核心思路:贪心策略
-
维护最远可达位置:
用max_reach
表示从起点出发,经过一系列跳跃后能到达的最远下标。初始时max_reach = 0
(起点位置)。- 遍历每个下标
i
,若i
在max_reach
范围内(即i <= max_reach
),说明可以从前面的某个位置跳跃到i
,此时更新max_reach
为i + nums[i]
(从i
出发能跳到的最远位置)和当前max_reach
中的较大值。 - 若
i
超出max_reach
(即i > max_reach
),说明无法到达i
,后续下标也无法到达,直接终止遍历。
- 遍历每个下标
-
提前终止条件:
一旦max_reach
覆盖最后一个下标(n - 1
),立即返回True
,无需遍历剩余元素,优化最坏情况下的时间复杂度。
复杂度分析
- 时间复杂度:( O(n) ),其中 ( n ) 是数组长度。每个元素仅遍历一次,每次操作均为常数时间。
- 空间复杂度:( O(1) ),仅使用常数级额外空间(
max_reach
和循环变量)。
示例推导
-
示例 1:
nums = [2, 3, 1, 1, 4]
i=0
:0 <= 0
,max_reach = max(0, 0+2=2)
→2
(未达终点,继续)。i=1
:1 <= 2
,max_reach = max(2, 1+3=4)
→4
(已达终点4
,返回True
)。
-
示例 2:
nums = [3, 2, 1, 0, 4]
i=0
:0 <= 0
,max_reach = 3
。i=1
:1 <= 3
,max_reach = 3
(1+2=3
)。i=2
:2 <= 3
,max_reach = 3
(2+1=3
)。i=3
:3 <= 3
,max_reach = 3
(3+0=3
)。i=4
:4 > 3
,跳出循环,返回False
。
关键点
- 贪心的本质:每次尽可能扩展可达范围,避免回溯或重复计算,确保线性时间复杂度。
- 边界处理:当数组长度为
1
时,直接返回True
(无需跳跃即可到达终点);当某位置不可达时,后续位置必然不可达,提前终止遍历。
该解法通过线性扫描和常数空间,高效解决了跳跃游戏问题,是此类问题的最优解法。
题目:跳跃游戏 II
给定一个非负整数数组 nums
,你最初位于数组的第一个位置,数组中的每个元素代表你在该位置可以跳跃的最大长度。目标是使用最少的跳跃次数到达最后一个位置。
解法:贪心算法
通过维护当前跳跃的最远可达位置 max_reach
和当前跳跃的终点 end
,遍历数组时更新这些变量。当到达当前跳跃的终点时,跳跃次数加 1
,并将终点更新为新的最远可达位置。若最远可达位置已覆盖最后一个位置,提前结束遍历。
Python 代码
from typing import List class Solution: def jump(self, nums: List[int]) -> int: n = len(nums) steps = 0 # 跳跃次数 end = 0 # 当前跳跃的终点 max_reach = 0 # 目前能到达的最远位置 for i in range(n - 1): max_reach = max(max_reach, i + nums[i]) if i == end: steps += 1 end = max_reach if end >= n - 1: break # 已到达或超过最后一个位置,提前结束 return steps
算法分析
- 时间复杂度:( O(n) ),遍历数组一次,每个元素处理时间为常数。
- 空间复杂度:( O(1) ),仅使用常数级额外空间。
该算法通过贪心策略,每次在可跳跃范围内找到最远可达位置,确保跳跃次数最少,高效解决问题。
题目:不同路径
一个机器人位于一个 m x n
网格的左上角,每次只能向下或者向右移动一步,试图达到网格的右下角。求总共有多少条不同的路径?
解法:动态规划
定义 dp[i][j]
表示到达网格 (i, j)
位置的不同路径数。
- 初始条件:
- 第一行
dp[0][j] = 1
(只能一直向右移动)。 - 第一列
dp[i][0] = 1
(只能一直向下移动)。
- 第一行
- 状态转移方程:
dp[i][j] = dp[i-1][j] + dp[i][j-1]
(从上方或左方到达)。
Python代码
from typing import List class Solution: def uniquePaths(self, m: int, n: int) -> int: dp = [[1] * n for _ in range(m)] for i in range(1, m): for j in range(1, n): dp[i][j] = dp[i-1][j] + dp[i][j-1] return dp[m-1][n-1]
优化空间(一维数组)
from typing import List class Solution: def uniquePaths(self, m: int, n: int) -> int: dp = [1] * n for i in range(1, m): for j in range(1, n): dp[j] += dp[j-1] return dp[n-1]
算法分析
- 时间复杂度:( O(m \times n) ),两层循环遍历网格。
- 空间复杂度:
- 二维数组:( O(m \times n) )。
- 一维数组:( O(n) ),优化后仅用一行数组存储状态。
通过动态规划,利用状态转移方程高效计算路径数,确保每个位置的路径数由相邻位置推导而来,最终得到右下角的路径总数。
相关文章:
面试算法高频08-动态规划-03
练习题 题目描述 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每…...
uniapp做app,使用v-for遍历渲染第二层的时候,打包到手机上渲染不出第二层的数据
1.打包apk要严格注意一点,在data中定义的时候要把第二层定义上, pointspower: [{ jcdbh: 1, cgqbhs:[] }] 不然会出现未定义的情况,直接把二层结构定义上,有利无害 2.渲染…...
Uniapp(vue):生命周期
目录 一、Vue生命周期二、Uniapp中页面的生命周期三、执行顺序比较一、Vue生命周期 setup():是在beforeCreate和created之前运行的,所以可以用setup代替这两个钩子函数。onBeforeMount():已经完成了模板的编译,但是组件还未挂载到DOM上的函数。onMounted():组件挂载到DOM完…...
Git技巧:Git Hook,自动触发,含实战分享
Git技巧:Git Hook,自动触发,含实战分享 最近项目需要1个git合入时触发脚本的功能,使用Git Hook功能实现,总结如下: Git项目在路径:repo\.git\hooks下有很多文件,这些文件就是本地钩…...
DeepSeek创始人梁文峰是个什么样的人?
梁文峰是一位在人工智能领域具有深远影响力的企业家和技术创新者,他的个人经历和成就展现了他作为一位技术天才、创新领袖以及社会责任感强的企业家的多重身份。 从学术背景来看,梁文峰出生于广东湛江吴川,17岁时以高考状元的身份考入浙江大…...
【知识科普】今天聊聊CDN
CDN 技术详解:从原理到配置实践 CDN 技术详解:从原理到配置实践一、CDN 核心定义二、工作原理深度解析1. 请求路由机制2. 缓存分层架构3. 内容更新流程 三、核心功能组件1. 基础设施层2. 软件系统 四、典型配置流程(以Cloudflare为例…...
Axure疑难杂症:利用中继器制作三级下拉菜单(逻辑判断进阶)
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:三级下拉菜单 主要内容:条件筛选时的逻辑判断思维,中继器使用 应用场景:复合条件下的下拉列表制作 案例展…...
C语言----操作符详解(万字详解)
目录 1. 操作符的分类 2. 二进制和进制转换 3. 原码 反码 补码 4. 移位操作符 4.1 左移操作符 >> 4.2 右移操作符 >> 5. 位操作符 5.1 按位与 & 5.2 按位或 | 5.3 按位异或 ^ 5.4 按位取反 ~ 练习 整数存储在内存中二进制中1的个数 练习 二进制位…...
docker本地部署ClipCascade,实现跨设备剪贴板同步
1、什么是 ClipCascade ? ClipCascade 是一款开源的轻量级工具,可以自动同步您的剪贴板在多个设备之间,无需按键。它确保设备之间无缝的剪贴板共享,并以端对端加密优先保护隐私。无论您是在不同工作站之间切换,还是仅…...
Android Compose vs 传统View系统:全面对比与选型指南
Android Compose vs 传统View系统:全面对比与选型指南 一、引言 随着Android Jetpack Compose的正式发布,Android开发迎来了全新的声明式UI框架。本文将全面对比Compose与传统View系统的差异,帮助开发者做出合理的技术选型。 二、核心架构…...
CVE-2024-3431 EyouCMS 反序列化漏洞研究分析
易优内容管理系统(EyouCms) 隶属于海口快推科技有限公司,专注中小型企业信息传播解决方案,利用网络传递信息在一定程度上提高了办事的效率,提高企业的竞争力。EyouCms 是一个自由和开放源码的内容管理系统,它是一个可以独立使用的…...
C# wpf
学习网址:控件的父类们 - WPF中文网 - 从小白到大佬 控件的父类: 由此我们可以得出结论,控件的父类们(准确的说,应该叫父类的父类的父类),至少有如下几个类型: DispatcherObjectDependencyObjectVisualU…...
十一、引用与拷贝函数(References the Copy-Constructor)
十一、引用与拷贝函数(References & the Copy-Constructor) 11.1 指针回顾(Review of pointers) 指针可以保存一个地址。 当你定义一个指针时,必须指定它所指向变量的类型,并且应该初始化它。 示例&a…...
数据结构之顺序表
目录 1.线性表 1.1 线性表的定义:零个或多个数据元素的有限序列。 1.2深度解析 1.3 线性表的抽象数据类型 2.顺序表 2.1 顺序表的定义和存储方式 2.2静态顺序表 2.2.1 静态顺序表的使用 2.2.3 为什么我们要使用typedef呢? 2.2.4 为什么我们要使…...
【计算机视觉】三种图像质量评价指标详解:PSNR、SSIM与SAM
图像质量评价指标详解:PSNR、SSIM与SAM 文章目录 图像质量评价指标详解:PSNR、SSIM与SAM1. 峰值信噪比(PSNR)1.1 数学定义1.2 特点与局限性 2. 结构相似性指数(SSIM)2.1 数学定义2.2 特点与应用 3. 光谱角度映射器(SAM)3.1 数学定义3.2 特点与应用 4. Py…...
轻舟系列FPGA加速卡:大模型分布式训练中的高效协同者
在超大规模模型(如千亿级参数)的分布式训练中,计算、存储与通信的协同优化是突破性能瓶颈的关键。绿算技术公司的轻舟系列FPGA加速卡凭借其低延迟、高能效和可编程特性,能够成为分布式训练架构中的异构加速节点。其在训练集群中的…...
C++20 小语法
这个提案允许在static_assert和if constexpr中从整形转换为布尔类型。 以下表格就可以表示所有内容。 对于严格的C 编译器来说,以前在这种情境下int无法向下转换为bool,需要手动强制转换, C23 这一情况得到了改善。 对于严格的C编译器来说&a…...
LM393比较器的比较翻转电压不对
问个问题,用的LM393比较器,3.3V供电,比较器输出上拉到3.3V, V给的基准2.8V,V-电压从1V升到2.3V,比较器就输出0V了,按理论超过2.8V才翻转到0V的 根据问题描述和电路分析,比较器LM393…...
解决 shadui组件库Popover 点击后会消失
react用了shadui组件库 <Popover><PopoverTrigger><div className"text-operation-item" onClick{props.callback}><img src{props.imgSrc} width{20} height{20} /></div></PopoverTrigger><PopoverContent className"…...
国联股份卫多多与北京慧闻科技(集团)签署战略合作协议
4月27日,北京慧闻科技(集团)有限公司(以下简称“慧闻科技”)销售总监王兴卓一行到访国联股份卫多多,同卫多多/纸多多副总裁、产发部总经理段任飞,卫多多机器人产业链总经理桂林展开深入交流&…...
从数据到决策:如何使用Python进行自动驾驶数据分析
从数据到决策:如何使用Python进行自动驾驶数据分析 大家好,我是Echo_Wish,今天来和大家聊一聊在自动驾驶领域中,如何通过Python进行数据分析。随着自动驾驶技术的不断发展,数据分析在这一领域的作用越来越重要。从传感器数据的处理到模型的训练和优化,Python在自动驾驶数…...
IIS服务器提示ERR_HTTP2 PROTOCOL ERROR解决方案
今天我的淘宝店来了一个客户,说小程序苹果访问没问题,安卓系统访问出现ERR HTTP2 PROTOCAL ERROR的错误见下图 方法供大家闭坑步骤:通过注册表修改(高级) 打开注册表编辑器 (regedit) 导航到: HKEY_LOCAL_MACHINE\SYSTEM\Current…...
Django的异步任务队列管理_Celery
1 基本原理 Celery 是一个异步任务队列,能够将耗时操作(如发邮件、处理图片、网络爬虫等)从 Django 主线程中分离出来,由后台的 worker 处理,避免阻塞请求。Celery 作为独立运行的后台进程(Worker…...
Ubuntu18.04安装IntelliJ IDEA2025步骤
1.下载linux版本的idea 复制下面链接到虚拟机浏览器 下载 IntelliJ IDEA 下载好后,你的文件里会多一个文件,如下图 2.解压并运行Idea 2.1在/usr/local/路径下新建安装目录IDEA: 打开终端输入以下命令: sudo mkdir -p /usr/loc…...
LLM - Large Language Model
回顾2024:与LLM又相伴一年的经历与思考 - 知乎万字长文入门大语言模型(LLM) - 知乎“大模型本质就是两个文件!”特斯拉前AI总监爆火LLM科普,时长1小时,面向普通大众 - 知乎大模型本质及趋势剖析,…...
解决Ubuntu20.04重启出现显卡驱动异常的问题(操作记录)
一、问题情况 电脑异常断电,重启后,显示界面异常,显卡驱动已丢失。 二、操作流程 1、查看安装显卡驱动 ls /usr/src | grep nvidia 记住该驱动,我的是nvidia-550.127.05 2、安装dkms(如果没有) sudo …...
23.开关电源干扰控制的EMC改善措施
开关电源干扰控制的EMC改善措施 1. 开关电源的EMI干扰机理2. 钳位抑制EMI3. 阻容吸收抑制EMI4. 波形整形抑制EMI 1. 开关电源的EMI干扰机理 2. 钳位抑制EMI 只能抑制Ts阶段。 3. 阻容吸收抑制EMI 4. 波形整形抑制EMI...
新能源汽车声纹监测技术的发展趋势是什么?
新能源汽车声纹监测技术有以下发展趋势: 智能化与自动化程度不断提高 故障自动诊断与预警:未来声纹监测系统将能够更加准确地自动识别和分析新能源汽车各部件的声纹特征变化,不仅能检测出故障,还能对故障的发展趋势进行预测&…...
如何获取按关键字搜索京东商品详情(代码示例)
在电商领域,获取京东商品的详细信息对于市场分析、选品上架、库存管理和价格策略制定等方面至关重要。京东作为国内知名的电商平台,提供了丰富的商品资源。通过 Python 爬虫技术,我们可以高效地获取京东商品的详细信息,包括商品名…...
C#中构造器及属性的加载顺序
一.基本原则: 先加载静态构造函数和静态字段,后加载普通构造函数和普通字段;先加载基类再加载子类; 二.具体的加载顺序: 父类静态字段--->父类静态构造函数--->子类静态字段--->子类静态构造函数--->父类实例字段---> 父类实例构造函数--->子类实例字段-…...
vue项目中如何使用markdown编辑器
在开发中,编辑markdown和回显markdown都是常见的需求。在vue(2.x和3.x都可以)中可以使用mavon-editor这个第三方依赖包。示例很简单易懂。 安装 npm install mavon-editor 注册 在main.js中注册这个组件 import Vue from vue import mavonEditor from mavon-editor impor…...
Python爬虫(9)Python数据存储实战:基于pymysql的MySQL数据库操作详解
目录 一、背景与核心价值二、pymysql核心操作详解2.1 环境准备2.2 数据库连接与基础操作2.3 事务处理与错误回滚2.4 高级功能:批量插入与性能优化 三、pymysql进阶技巧3.1 连接池管理(推荐使用DBUtils)3.2 SQL注入防御3.3 与ORM框架对比 四、…...
WPF之Button控件详解
文章目录 1. 引言2. Button控件基础Button类定义 3. Button控件的核心属性3.1 Content属性3.2 IsDefault属性3.3 IsCancel属性3.4 其他常用属性 4. 按钮样式与模板自定义4.1 简单样式设置4.2 使用Style对象4.3 触发器使用4.4 使用ControlTemplate完全自定义4.5 按钮视觉状态 5.…...
如何查看电脑电池使用情况
第一步打开cmd: 在键盘上按下winr 或者在搜索框中输入cmd 点击命令提示符 进入命令框 第二步输入命令: powercfg/batteryreport 出现如下情况 第三部找到对应电池报告进行查看: 在对应路径下找到电池报告 点击battery-report.html 到此…...
软考-软件设计师中级备考 6、数据结构 图
1. 有向图 有向图是由顶点集合 V 和有向边集合 E 组成的图结构。在有向图中,边是有方向的,即从一个顶点指向另一个顶点,通常用有序对 (u, v) 表示,其中 u 是边的起始顶点,v 是边的终止顶点。例如,在一个表…...
Label Studio 软件介绍及安装使用说明
背景说明 在做AI项目建模的时候,往往需要数据标注工作,比较常用的数据标注软件是Labeling或者Labelme,这两个都是离线的单独标注软件,使用起来是比较方便的,也是入门级学者比较适合的软件,然而有时候我们数据标注的数据…...
Azure 数字孪生是什么?
“Azure 数字孪生”是一项平台即服务 (PaaS) 产品/服务,它能够创建基于整个环境的数字模型的孪生图,这些图可能是建筑物、工厂、农场、能源网络、铁路、体育场馆,甚至整个城市。 这些数字模型可用于获取洞察力,以推动产品改进、运…...
界面控件DevExpress WPF v25.1预览 - AI功能增强(语义搜索)
DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...
【神经网络与深度学习】五折交叉验证(5-Fold Cross-Validation)
引言 五折交叉验证(5-Fold Cross-Validation)是一种广泛应用于机器学习模型性能评估的技术,通过多次实验确保模型的评估结果更加稳定、可靠,同时最大限度地利用有限的数据资源。它将数据分成若干子集,交替作为训练集和…...
Linux权限概念讲解
1. 用户类型 1.1 用户分类 在Linux里面用户分为两类,一种是超级用户(root),一种是普通用户。 超级用户只有一个,而普通用户可以有很多个。 如果我们在root用户状态下想要变成普通用户,我们可以使用命令…...
网络安全零基础培训 L1-8 PHP基础语法
文章目录 1 认识PHP1.1 PHP简介1.2 主要的特点1.3 跨平台性1.4 与数据库的良好集成1.5 开源和社区支持1.6 应用场景1.6.1 网站开发1.6.2 内容的管理程序1.6.3 Web应用程序开发1.6.4 为什么学习了解PHP 2 PHP的基础语法2.1 创建第一个PHP程序2.2 如何写注释2.3 PHP的变量2.4 PHP…...
鸿蒙 长列表加载性能优化
长列表加载性能优化 针对长列表加载这一场景,对列表渲染时间、页面滑动帧率、应用内存占用等方面带来优化,提升性能和用户体验的手段有如下 4 种: 懒加载:提供列表数据按需加载能力,解决一次性加载长列表数据耗时长、…...
第十二届蓝桥杯 2021 C/C++组 卡片
目录 题目: 题目描述: 题目链接: 思路: 思路详解: 代码: 代码详解: 题目: 题目描述: 题目链接: 卡片 - 蓝桥云课 思路: 思路详解&#…...
vscode 使用gitcode团队管理项目
1、下载安装vscode https://code.visualstudio.com/Download 2、安装git 3、在vscode中安装GitLens插件 4、打开终端 点击会显示当前更改的项目 5、提交更改的文件,会提示输入用户名、密码,这里的密码即是令牌,令牌在第一次创建的时候显…...
uniapp+vue3+ts 使用canvas实现安卓端、ios端及微信小程序端二维码生成及下载
加粗样式uniapp多端生成带二维码海报并保存至相册的实现 在微信小程序开发中,我们常常会遇到生成带有二维码的海报并保存到手机相册的需求,比如分享活动海报、产品宣传海报等。今天就来和大家分享一下如何通过代码实现这一功能。 准备工作 在开始之前&am…...
vue mixin混入与hook
mixin混入是 选项式 API,在vue3-Composition API <script setup> 中无法直接使用,需通过 setup() 函数转换 vue2、vue3选项式API: // mixins/mixin.js export const mixin {methods: {courseType(courseLevel) {const levelMap {1: 初级,…...
《Masked Autoencoders Are Scalable Vision Learners》---CV版的BERT
目录 一、与之前阅读文章的关系? 二、标题:带掩码的自auto编码器是一个可拓展的视觉学习器 三、摘要 四、核心图 五、结果图 六、不同mask比例对比图 七、“Introduction” (He 等, 2021, p. 1) 引言 八、“Related Work” (He 等, 2021, p. 3)相…...
(云计算HCIP)HCIP全笔记(十三)本篇介绍虚拟化技术,内容包含:虚拟化资源、虚拟化过程、I/O虚拟化、虚拟化架构KVM和Xen介绍、主流虚拟化技术介绍
1. 虚拟化资源 1.1 虚拟化对象 CPU虚拟化: 目标是使虚拟机上的指令能被正常执行,且效率接近物理机 内存虚拟化: 目标是能做好虚拟机内存空间之 间的隔离,使每个虚拟机都认为自己拥有了整个内存地址,且效率页能接近物理…...
C++核心编程:类与对象全面解析
C核心编程:类与对象全面解析 大家好!今天我要和大家深入探讨C面向对象编程中最核心的概念:类与对象。👨💻 这是我们迈向高级C开发的第一步,掌握好这部分内容,对未来学习更高级的设计模式和框…...
Linux基础命令和文件系统结构:从入门到实践
目录 1. 引言 2. Linux文件系统结构概述 2.1 根目录 编辑 2.2 常见目录介绍: 1. /home:用户的家目录 2. /etc:存放配置文件的目录 3. /var:可变数据 4. /bin 和 /sbin:常见命令和系统管理工具 5. /tmp&…...