网站可行性公司邮箱域名怎么起

张小明 2026/1/5 18:19:05
网站可行性,公司邮箱域名怎么起,河南省建筑资质查询,淘宝联盟必须要网站备案数组题目总结笔记#xff08;二#xff09; 目录 最长公共前缀加一杨辉三角买卖股票的最佳时机多数元素6. 最长公共前缀 题目描述 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀#xff0c;返回空字符串 “”。 示例#xff1a; 输入#xff1a;strs…数组题目总结笔记二目录最长公共前缀加一杨辉三角买卖股票的最佳时机多数元素6. 最长公共前缀题目描述编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀返回空字符串 “”。示例输入strs [flower, flow, flight] 输出fl 输入strs [dog, racecar, car] 输出 解释输入不存在公共前缀。提示1 strs.length 2000 strs[i].length 200strs[i]如果非空则仅由小写英文字母组成解法横向扫描classSolution:deflongestCommonPrefix(self,strs:List[str])-str:# 处理空数组情况ifnotstrs:return# 以第一个字符串作为基准prefixstrs[0]# 遍历剩余的字符串foriinrange(1,len(strs)):# 关键不断缩短前缀直到找到公共前缀whilenotstrs[i].startswith(prefix):prefixprefix[:-1]# 如果前缀为空说明没有公共前缀ifnotprefix:returnreturnprefix代码注释if not strs: return : 处理空数组的边界情况如果没有字符串直接返回空字符串prefix strs[0]: 将第一个字符串作为初始前缀这是我们的基准字符串for i in range(1, len(strs)): 从第二个字符串开始遍历与基准前缀进行比较while not strs[i].startswith(prefix): **这是核心逻辑**当当前字符串不以prefix开头时说明prefix太长了prefix prefix[:-1]: **关键操作**每次将前缀缩短一个字符去掉最后一个字符if not prefix: return : 如果前缀被缩短到空字符串说明没有任何公共前缀直接返回return prefix: 遍历完所有字符串后prefix就是最长公共前缀知识点讲解1. 横向扫描法逐字符串比较核心思想以第一个字符串为基准依次与其他字符串比较不断缩短前缀直到找到公共部分时间复杂度O(S)其中S是所有字符串中字符的总数空间复杂度O(1)只使用了几个变量优势思路直观代码简洁2. 为什么用 startswith() 方法startswith(prefix)检查字符串是否以指定前缀开头时间复杂度 O(m)其中m是前缀长度这是Python字符串的内置方法比手动逐个字符比较更高效示例strs[i].startswith(fl)检查 “flower” 是否以 “fl” 开头返回 True3. 执行过程示例初始strs [flower, flow, flight] prefix flower 第1次循环i1, strs[1]flow flow.startswith(flower) False prefix flowe去掉最后一个字符r flow.startswith(flowe) False prefix flow去掉最后一个字符e flow.startswith(flow) True ✓ 此时 prefix flow 第2次循环i2, strs[2]flight flight.startswith(flow) False prefix flo去掉最后一个字符w flight.startswith(flo) False prefix fl去掉最后一个字符o flight.startswith(fl) True ✓ 此时 prefix fl 最终返回fl4. 其他解法思路纵向扫描逐个字符位置比较所有字符串遇到不同字符就停止分治法将数组分成两部分分别求公共前缀再合并二分查找对最短字符串的长度进行二分检查某个长度是否满足公共前缀5. 边界情况处理空数组返回 “”只有一个字符串返回该字符串本身存在空字符串如果数组中存在空字符串公共前缀一定是 “”所有字符串完全相同返回任意一个字符串7. 加一题目描述给定一个由整数组成的非空数组所表示的非负整数在该数的基础上加一。最高位数字存放在数组的首位 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外这个整数不会以零开头。示例输入digits [1,2,3] 输出[1,2,4] 解释输入数组表示数字 123。加 1 后得到 123 1 124。因此结果应该是 [1,2,4]。 输入digits [4,3,2,1] 输出[4,3,2,2] 解释输入数组表示数字 4321。加 1 后得到 4321 1 4322。因此结果应该是 [4,3,2,2]。 输入digits [9] 输出[1,0] 解释输入数组表示数字 9。加 1 后得到了 9 1 10。因此结果应该是 [1,0]。解法模拟加法进位classSolution:defplusOne(self,digits:List[int])-List[int]:# 从最后一位开始加1foriinrange(len(digits)-1,-1,-1):# 关键当前位加1后如果小于10直接返回digits[i]1digits[i]%10# 如果当前位不是0说明没有进位直接返回ifdigits[i]!0:returndigits# 如果所有位都是0说明需要增加一位如99911000return[1]digits代码注释for i in range(len(digits) - 1, -1, -1): 从数组末尾开始向前遍历模拟从个位到高位的加法digits[i] 1: **关键操作**当前位加1digits[i] % 10: **关键操作**取模运算如果当前位是10则变为0进位否则保持原值if digits[i] ! 0: return digits: 如果当前位不是0说明没有产生进位加法完成直接返回return [1] digits: **特殊情况**如果所有位都变成了0如9991需要在最前面添加一个1知识点讲解1. 模拟手工加法的过程核心思想从最低位数组末尾开始逐位加1处理进位就像我们手工计算一样个位加1如果等于10就进位十位加1以此类推时间复杂度O(n)最坏情况需要遍历整个数组空间复杂度O(1)除了结果数组外只使用了常数空间2. 为什么用 % 10取模运算digits[i] % 10等价于digits[i] digits[i] % 10当digits[i] 10时10 % 10 0表示进位当digits[i] 10时digits[i] % 10 digits[i]保持不变这是处理进位的简洁方法避免了 if-else 判断3. 执行过程示例示例1digits [1,2,3]初始digits [1,2,3] i2个位 digits[2] 1 → digits[2] 4 digits[2] % 10 → digits[2] 4 digits[2] ! 0 → 返回 [1,2,4] ✓示例2digits [1,9,9]初始digits [1,9,9] i2个位 digits[2] 1 → digits[2] 10 digits[2] % 10 → digits[2] 0进位 digits[2] 0 → 继续循环 i1十位 digits[1] 1 → digits[1] 10 digits[1] % 10 → digits[1] 0进位 digits[1] 0 → 继续循环 i0百位 digits[0] 1 → digits[0] 2 digits[0] % 10 → digits[0] 2 digits[0] ! 0 → 返回 [2,0,0] ✓示例3digits [9,9,9]初始digits [9,9,9] i2digits[2] 0进位 i1digits[1] 0进位 i0digits[0] 0进位 所有位都是0 → 返回 [1] [0,0,0] [1,0,0,0] ✓4. 关键技巧提前返回优化if digits[i] ! 0: return digits这行代码非常关键一旦某一位加1后不是0说明没有产生进位后面的高位不需要再处理这大大提高了效率避免了不必要的遍历例如[1,2,3] 加1时个位变成4后就可以直接返回不需要检查十位和百位5. 特殊情况全9的情况当所有位都是9时如999加1后所有位都变成0需要在最前面添加1return [1] digits巧妙地处理了这种情况[1] [0,0,0] [1,0,0,0]正确表示了10006. 为什么从后往前遍历因为加法是从最低位个位开始的如果从前往后遍历无法正确处理进位例如199 1必须先处理个位产生进位后再处理十位8. 杨辉三角题目描述给定一个非负整数 numRows生成「杨辉三角」的前 numRows 行。在「杨辉三角」中每个数是它左上方和右上方的数的和。示例输入numRows 5 输出[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 输入numRows 1 输出[[1]]解法动态规划逐行构建classSolution:defgenerate(self,numRows:int)-List[List[int]]:# 初始化结果列表result[]# 遍历每一行foriinrange(numRows):# 创建当前行初始化为全1row[1]*(i1)# 关键从第2行开始i1计算中间的值forjinrange(1,i):# 核心公式当前值 上一行的左上方 上一行的右上方row[j]result[i-1][j-1]result[i-1][j]# 将当前行添加到结果中result.append(row)returnresult代码注释result []: 初始化结果列表用于存储所有行for i in range(numRows): 遍历每一行i表示行号从0开始row [1] * (i 1): **关键初始化**创建长度为(i1)的列表全部初始化为1第0行有1个元素第1行有2个元素第i行有(i1)个元素首尾都是1所以先全部设为1再修改中间的值for j in range(1, i): 从第2行开始i1遍历中间的元素不包括首尾j从1开始到i-1结束正好是中间的元素row[j] result[i - 1][j - 1] result[i - 1][j]:核心公式result[i - 1]是上一行result[i - 1][j - 1]是上一行的左上方元素result[i - 1][j]是上一行的右上方元素同一列result.append(row): 将当前行添加到结果中知识点讲解1. 杨辉三角的数学性质杨辉三角是二项式系数的三角形排列第n行第k个数 C(n,k) n! / (k! * (n-k)!)每个数等于它上方两个数的和除了首尾的1对称性第n行从左到右和从右到左是对称的2. 动态规划思想状态定义result[i][j]表示第i行第j列的值状态转移result[i][j] result[i-1][j-1] result[i-1][j]边界条件每行的首尾都是1核心思想利用上一行的结果计算当前行避免重复计算3. 为什么先初始化为全1row [1] * (i 1)这行代码非常巧妙杨辉三角的每一行首尾都是1中间的值需要计算先全部设为1然后只修改中间的值代码更简洁避免了分别处理首尾和中间的复杂逻辑4. 执行过程示例numRows 5 i0第1行 row [1] * 1 [1] j循环不执行因为range(1,0)为空 result [[1]] i1第2行 row [1] * 2 [1,1] j循环不执行因为range(1,1)为空 result [[1], [1,1]] i2第3行 row [1] * 3 [1,1,1] j1: row[1] result[1][0] result[1][1] 1 1 2 row [1,2,1] result [[1], [1,1], [1,2,1]] i3第4行 row [1] * 4 [1,1,1,1] j1: row[1] result[2][0] result[2][1] 1 2 3 j2: row[2] result[2][1] result[2][2] 2 1 3 row [1,3,3,1] result [[1], [1,1], [1,2,1], [1,3,3,1]] i4第5行 row [1] * 5 [1,1,1,1,1] j1: row[1] result[3][0] result[3][1] 1 3 4 j2: row[2] result[3][1] result[3][2] 3 3 6 j3: row[3] result[3][2] result[3][3] 3 1 4 row [1,4,6,4,1] result [[1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1]]5. 索引关系详解result[i-1][j-1]上一行的左上方元素第i-1行第j-1列result[i-1][j]上一行的正上方元素同一列第i-1行第j列这两个元素在杨辉三角中正好是当前元素的上方两个数6. 时间复杂度与空间复杂度时间复杂度O(numRows²)需要计算O(numRows²)个元素空间复杂度O(numRows²)需要存储所有行的数据优化空间如果只需要返回第n行可以优化到O(n)空间7. 边界情况处理numRows 0返回空列表 []numRows 1返回 [[1]]每行的首尾元素始终为1不需要计算9. 买卖股票的最佳时机题目描述给定一个数组 prices 它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择某一天买入这只股票并选择在未来的某一个不同的日子卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润返回 0 。示例输入[7,1,5,3,6,4] 输出5 解释在第 2 天股票价格 1的时候买入在第 5 天股票价格 6的时候卖出最大利润 6-1 5。 注意利润不能是 7-1 6因为卖出价格需要大于买入价格同时你不能在买入前卖出股票。 输入prices [7,6,4,3,1] 输出0 解释在这种情况下, 没有交易完成, 所以最大利润为 0。提示1 prices.length 10^5解法一次遍历贪心算法classSolution:defmaxProfit(self,prices:List[int])-int:# 初始化最小买入价格和最大利润min_pricefloat(inf)max_profit0# 遍历每一天的价格forpriceinprices:# 关键更新最小买入价格min_pricemin(min_price,price)# 关键计算当前卖出能获得的利润并更新最大利润max_profitmax(max_profit,price-min_price)returnmax_profit代码注释min_price float(inf): 初始化最小买入价格为无穷大确保第一次比较时能正确更新max_profit 0: 初始化最大利润为0如果无法盈利则返回0for price in prices: 遍历每一天的股票价格min_price min(min_price, price): **关键操作**记录到目前为止的最低买入价格如果今天的价格更低更新最小买入价格这样我们总是用历史最低价作为买入价格max_profit max(max_profit, price - min_price):核心逻辑计算如果今天卖出能获得的利润 今天价格 - 历史最低买入价如果这个利润大于之前记录的最大利润就更新最大利润return max_profit: 返回整个过程中能获得的最大利润知识点讲解1. 贪心算法思想核心思想在遍历过程中维护两个关键变量历史最低买入价格min_price到目前为止的最大利润max_profit贪心策略对于每一天我们考虑如果在这一天卖出能获得的最大利润利润 今天价格 - 历史最低买入价我们只需要记录最大的利润即可2. 为什么只需要一次遍历关键 insight要获得最大利润必须在历史最低价买入如果我们知道历史最低价是 min_price那么在第i天卖出的利润就是prices[i] - min_price我们只需要遍历一次同时更新最低价和最大利润时间复杂度O(n)只需遍历一次数组空间复杂度O(1)只使用了两个变量3. 执行过程示例prices [7,1,5,3,6,4] 初始min_price inf, max_profit 0 第1天price7 min_price min(inf, 7) 7 max_profit max(0, 7-7) max(0, 0) 0 第2天price1 min_price min(7, 1) 1 ← 更新最低价 max_profit max(0, 1-1) max(0, 0) 0 第3天price5 min_price min(1, 5) 1 ← 保持最低价 max_profit max(0, 5-1) max(0, 4) 4 ← 更新最大利润 第4天price3 min_price min(1, 3) 1 max_profit max(4, 3-1) max(4, 2) 4 第5天price6 min_price min(1, 6) 1 max_profit max(4, 6-1) max(4, 5) 5 ← 更新最大利润 第6天price4 min_price min(1, 4) 1 max_profit max(5, 4-1) max(5, 3) 5 最终返回54. 为什么用 float(‘inf’)float(inf)表示正无穷大初始化 min_price 为无穷大确保第一次比较时 prices[0] 一定能更新 min_price如果初始化为 prices[0]代码也能工作但使用 inf 更通用Python中也可以用sys.maxsize或prices[0]如果数组非空5. 关键理解为什么这样能保证先买后卖虽然我们在遍历过程中同时更新买入价和卖出价但逻辑上min_price 记录的是到目前为止的最低价max_profit 记录的是如果今天卖出能获得的最大利润由于我们是从前往后遍历min_price 总是在当前 price 之前出现的价格所以price - min_price一定是先买后卖的利润6. 边界情况处理空数组如果 prices 为空循环不执行返回 0价格一直下跌max_profit 始终保持为 0返回 0价格一直上涨min_price 是第一个价格max_profit 是最后一个价格减去第一个价格7. 动态规划视角扩展理解这个问题也可以用动态规划解决dp[i][0]第i天持有股票的最大利润买入dp[i][1]第i天不持有股票的最大利润卖出但贪心算法更简洁高效空间复杂度O(1)10. 多数元素题目描述给定一个大小为 n 的数组 nums 返回其中的多数元素。多数元素是指在数组中出现次数大于 ⌊n/2⌋的元素。你可以假设数组是非空的并且给定的数组总是存在多数元素。示例输入nums [3,2,3] 输出3 输入nums [2,2,1,1,1,2,2] 输出2提示n nums.length1 n 5 * 10^4-10^9 nums[i] 10^9解法Boyer-Moore 投票算法classSolution:defmajorityElement(self,nums:List[int])-int:# 初始化候选人和计数器candidateNonecount0# 第一阶段找出可能的多数元素fornuminnums:# 关键如果计数器为0选择当前元素作为候选人ifcount0:candidatenum# 关键如果当前元素等于候选人计数器加1否则减1ifnumcandidate:count1else:count-1# 第二阶段验证本题可以省略因为题目保证存在多数元素# 由于题目保证存在多数元素candidate 就是答案returncandidate代码注释candidate None: 初始化候选人为None表示还没有选择候选人count 0: 初始化计数器为0for num in nums: 遍历数组中的每个元素if count 0: candidate num:关键操作当计数器归零时说明之前的候选人被抵消完了选择当前元素作为新的候选人这保证了我们总是有一个候选人在竞争if num candidate: count 1: 如果当前元素等于候选人支持票1else: count - 1: 如果当前元素不等于候选人反对票-1抵消一票return candidate: 遍历结束后candidate 就是多数元素知识点讲解1. Boyer-Moore 投票算法的核心思想算法原理多数元素的出现次数 n/2所以它比其他所有元素加起来还多如果把多数元素看作1其他元素看作-1那么所有元素的和一定 0算法通过抵消的思想最终剩下的就是多数元素2. 为什么这个算法有效关键 insight多数元素的数量 n/2假设多数元素有 k 个其他元素有 n-k 个由于 k n/2所以 k n-k即使所有非多数元素都用来抵消多数元素多数元素仍然会有剩余k - (n-k) 2k - n 03. 执行过程示例示例1nums [3,2,3]初始candidate None, count 0 num3 count 0 → candidate 3 num candidate → count 1 num2 count ! 0 → 不更新candidate num ! candidate → count 0抵消 num3 count 0 → candidate 3 num candidate → count 1 最终candidate 3 ✓示例2nums [2,2,1,1,1,2,2]初始candidate None, count 0 num2candidate2, count1 num2candidate2, count2 num1candidate2, count1抵消 num1candidate2, count0抵消 num1count0 → candidate1, count1 num2candidate1, count0抵消 num2count0 → candidate2, count1 最终candidate 2 ✓4. 为什么 count 0 时要更新 candidate当 count 0 时说明之前的候选人和非候选人完全抵消了前面的元素中候选人和非候选人的数量相等这些元素对后续的结果没有影响可以丢弃从当前位置开始重新选择候选人这保证了算法能正确找到多数元素5. 时间复杂度与空间复杂度时间复杂度O(n)只需遍历一次数组空间复杂度O(1)只使用了两个变量candidate 和 count**这是最优解**比哈希表方法O(n)空间更优6. 与其他方法的对比方法时间复杂度空间复杂度哈希表统计O(n)O(n)排序O(n log n)O(1)Boyer-Moore投票算法O(n)O(1)7. 算法正确性证明简化版设多数元素为 x出现次数为 kk n/2其他元素总数为 n-kn-k n/2算法过程中每个 x 贡献 1每个非 x 贡献 -1最终计数 k - (n-k) 2k - n 0所以最终 candidate 一定是 x8. 边界情况处理数组只有一个元素candidate 就是该元素count 1所有元素相同candidate 始终保持不变count 一直增加题目保证存在多数元素不需要验证阶段9. 扩展如果需要验证 candidate 是否是真正的多数元素如果题目不保证存在多数元素需要第二阶段验证count0fornuminnums:ifnumcandidate:count1ifcountlen(nums)//2:returncandidateelse:returnNone# 或抛出异常总结数组题目的核心技巧续6. 字符串处理技巧startswith()方法检查前缀用于最长公共前缀问题字符串切片prefix[:-1]用于缩短字符串时间复杂度字符串操作通常是 O(m)m 是字符串长度7. 模拟运算模拟手工计算过程如加一问题从低位到高位处理取模运算用于处理进位digits[i] % 10提前返回优化一旦确定结果就可以返回避免不必要的计算8. 动态规划状态定义明确dp[i]或dp[i][j]的含义状态转移找到当前状态与之前状态的关系边界条件处理初始状态和特殊情况杨辉三角典型的二维动态规划问题9. 贪心算法局部最优每一步都做出当前最优的选择全局最优局部最优的选择最终导致全局最优买卖股票维护历史最低价和最大利润关键证明贪心策略的正确性10. 投票算法Boyer-Moore 算法用于找多数元素核心思想抵消 重新选择优势O(1) 空间复杂度O(n) 时间复杂度适用场景找出现次数超过一半的元素思考题1. 最长公共前缀的变种题目如果要求找到最长公共后缀如何修改代码提示可以从后往前比较或者反转字符串后使用相同的方法。2. 加一的扩展题目如果不是加1而是加一个任意的数字 k如何实现提示需要处理更复杂的进位情况可能需要额外的变量来存储进位值。3. 杨辉三角的变种题目如果只需要返回第 n 行从0开始如何优化空间复杂度到 O(n)提示只需要维护上一行的结果不需要存储所有行。4. 买卖股票的扩展题目如果可以多次买卖但必须先卖后买如何计算最大利润提示贪心策略只要后一天价格高于前一天就进行交易。5. 多数元素的扩展题目如果数组中不存在多数元素如何修改代码来返回 None提示需要添加验证阶段统计 candidate 的实际出现次数。推荐练习顺序入门最长公共前缀、加一进阶杨辉三角、多数元素提高买卖股票的最佳时机版权声明本文为原创文章遵循 CC 4.0 BY-SA 版权协议转载请附上原文出处链接及本声明。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

东莞制作网站公司哪家好蚌埠哪有做网站的

Sun RPC:认证、超时重传及相关机制详解 1. Unix认证机制及其局限性 Unix认证在实际应用中很少被采用,因为它很容易被破解。攻击者能够轻松构建包含Unix认证信息的RPC数据包,随意设置用户ID和组ID,然后将其发送给服务器,而服务器却无法验证发送者的真实身份。 NFS默认采…

张小明 2025/12/28 19:38:46 网站建设

网站上传服务器教程品牌建设的论文

光照探针的作用光照探针(Light Probes)是Unity中用于解决动态物体间接光照问题的核心技术,主要作用包括:‌为动态物体提供间接光照‌:在静态场景中,动态物体无法直接使用烘焙光照贴图,光照探针通过存储空间中的光照信息…

张小明 2025/12/30 8:56:29 网站建设

白城网站建设哪家好js开发手机app

本文内容速览: 一、什么是基因敲高? 在给大家介绍基因敲高的概念之前,先给大家介绍一下基因敲除(Knock-out,KO)的概念。基因敲除是20世纪80年代以来发展起来的一种新型分子生物学技术,该技术通…

张小明 2025/12/28 12:49:49 网站建设

网站流量赚钱腾讯qq网页版

第一章:自动化测试工具变革的背景与意义随着软件开发模式向敏捷与持续交付演进,传统手动测试已难以满足高频迭代下的质量保障需求。自动化测试工具的演进成为提升测试效率、降低回归成本的关键驱动力。现代应用架构的复杂化,如微服务、容器化…

张小明 2025/12/29 4:45:50 网站建设

网站seo专员招聘做家具定制的设计网站

你是不是也这样:下载的PDF堆满文件夹,想找的时候死活记不住名字;读文献时灵感一闪,回头却找不到记在哪了;写论文时,调整一个引用格式就要折腾半小时…文献管理不是小事,它直接决定了你的研究效率…

张小明 2026/1/1 0:19:27 网站建设

有没有专门做网站的网站建设企业名录

目录 一、概念区分 1.产业链 2.供应链 3.价值链 二、那么,不协同具体会带来哪些问题? 1.目标不一致导致的行动矛盾 2.部门之间的优化相互冲突 3.创新想法受制于现实条件 三、怎么才能推动协同? 第一步,从统一目标和评价…

张小明 2026/1/1 19:01:50 网站建设