ARTICLE · 1105423
2026网安习题大全(8)
题目71:合并区间
问题描述:给定一个区间数组 intervals,其中 intervals[i] = [start_i, end_i],合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
解题思路:先按区间的左端点排序。然后遍历区间,若当前区间的左端点小于等于结果数组中最后一个区间的右端点,则说明有重叠,合并两者(更新右端点为两者的较大值);否则将当前区间加入结果数组。
Python 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def merge(intervals): if not intervals: return [] intervals.sort(key=lambda x: x[0]) merged = [intervals[0]] for start, end in intervals[1:]: if start <= merged[-1][1]: merged[-1][1] = max(merged[-1][1], end) else: merged.append([start, end]) return merged
题目72:插入区间
问题描述:给定一个无重叠的、按照区间起始端点排序的区间列表 intervals,以及一个新的区间 newInterval,将新区间插入到列表中,并保持列表仍然有序且不重叠(如有必要则合并重叠区间)。
解题思路:遍历区间列表,分三步处理:先将所有在新区间左侧且不重叠的区间加入结果;然后处理与新区间重叠的区间,不断合并到新区间中;最后将剩余区间加入结果。
Python 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 def insert(intervals, newInterval): result = [] i = 0 n = len(intervals) # 左侧不重叠区间 while i < n and intervals[i][1] < newInterval[0]: result.append(intervals[i]) i += 1 # 合并重叠区间 while i < n and intervals[i][0] <= newInterval[1]: newInterval[0] = min(newInterval[0], intervals[i][0]) newInterval[1] = max(newInterval[1], intervals[i][1]) i += 1 result.append(newInterval) # 右侧剩余区间 while i < n: result.append(intervals[i]) i += 1 return result
题目73:用最少数量的箭引爆气球
问题描述:给定一个数组 points,其中 points[i] = [x_start, x_end] 表示一个气球的水平直径范围。一支箭可以垂直向上射穿所有满足 x_start <= x <= x_end 的气球。求引爆所有气球所需的最少箭数。
解题思路:使用贪心算法。先按气球的右端点排序。每次选择当前未引爆气球的右端点作为射箭位置,然后跳过所有左端点小于等于该位置的气球(即被这支箭引爆)。重复直到所有气球被引爆。
Python 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def findMinArrowShots(points): if not points: return 0 points.sort(key=lambda x: x[1]) arrows = 1 arrow_pos = points[0][1] for start, end in points[1:]: if start > arrow_pos: arrows += 1 arrow_pos = end return arrows
题目74:根据身高重建队列
问题描述:给定一个数组 people,其中 people[i] = [h_i, k_i] 表示第 i 个人的身高为 h_i,且前面正好有 k_i 个身高大于或等于 h_i 的人。请重建并返回这个队列。
解题思路:先按身高降序、人数升序排序。然后依次将每个人插入到结果列表中索引为 k_i 的位置。由于先处理高个子,后面插入的矮个子不会影响已插入高个子的 k 值。
Python 代码示例:
1 2 3 4 5 6 7 8 def reconstructQueue(people): people.sort(key=lambda x: (-x[0], x[1])) result = [] for person in people: result.insert(person[1], person) return result
题目75:跳跃游戏 II
问题描述:给定一个非负整数数组 nums,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用最少的跳跃次数到达数组的最后一个位置。
解题思路:使用贪心算法。维护当前跳跃能到达的最远位置 cur_end 和下一次跳跃能到达的最远位置 farthest。遍历数组,每到一个位置就更新 farthest。当遍历到 cur_end 时,说明需要进行一次跳跃,更新 cur_end = farthest 并增加跳跃次数。
Python 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 def jump(nums): jumps = 0 cur_end = 0 farthest = 0 for i in range(len(nums) - 1): farthest = max(farthest, i + nums[i]) if i == cur_end: jumps += 1 cur_end = farthest return jumps
题目76:字符串相乘
问题描述:给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。不能使用任何内置的大整数库,也不能直接将输入字符串转换为整数。
解题思路:模拟竖式乘法。创建一个长度为 len(num1) + len(num2) 的结果数组。从右向左遍历两个字符串的每一位,将乘积累加到结果数组的对应位置,并处理进位。最后将结果数组转换为字符串,去掉前导零。
Python 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def multiply(num1, num2): if num1 == "0" or num2 == "0": return "0" m, n = len(num1), len(num2) result = [0] * (m + n) for i in range(m - 1, -1, -1): for j in range(n - 1, -1, -1): mul = int(num1[i]) * int(num2[j]) p1, p2 = i + j, i + j + 1 total = mul + result[p2] result[p2] = total % 10 result[p1] += total // 10 res_str = ''.join(map(str, result)).lstrip('0') return res_str if res_str else "0"
题目77:两数相除
问题描述:给定两个整数 dividend 和 divisor,在不使用乘法、除法和取余运算的情况下,计算 dividend 除以 divisor 的商。结果需要截断为整数部分。假设环境只能存储 32 位有符号整数。
解题思路:使用位运算和减法模拟除法。将被除数和除数都转为正数处理,通过不断将除数左移(乘以 2)来快速逼近被除数,记录对应的倍数并累加商。最后根据符号确定结果,并处理溢出情况。
Python 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def divide(dividend, divisor): if dividend == -2**31 and divisor == -1: return 2**31 - 1 negative = (dividend < 0) != (divisor < 0) dividend, divisor = abs(dividend), abs(divisor) quotient = 0 while dividend >= divisor: temp = divisor multiple = 1 while dividend >= (temp << 1): temp <<= 1 multiple <<= 1 dividend -= temp quotient += multiple return -quotient if negative else quotient
题目78:分数到小数
问题描述:给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。如果小数部分为循环小数,则将循环的部分括在括号内。
解题思路:先处理符号和整数部分。然后用哈希表记录每个余数出现的位置,模拟长除法。若余数重复出现,说明进入循环,插入括号。若余数为 0,则除法结束。
Python 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 def fractionToDecimal(numerator, denominator): if numerator == 0: return "0" result = [] if (numerator < 0) != (denominator < 0): result.append("-") num, den = abs(numerator), abs(denominator) result.append(str(num // den)) remainder = num % den if remainder == 0: return ''.join(result) result.append(".") seen = {} while remainder != 0: if remainder in seen: result.insert(seen[remainder], "(") result.append(")") break seen[remainder] = len(result) remainder *= 10 result.append(str(remainder // den)) remainder %= den return ''.join(result)
题目79:阶乘后的零
问题描述:给定一个整数 n,返回 n! 结果中尾随零的数量。
解题思路:尾随零的个数取决于因子中 10 的个数,而 10 由 2 和 5 组成。由于阶乘中 2 的数量远多于 5,因此只需统计因子 5 的个数。即 n/5 + n/25 + n/125 + ...。
Python 代码示例:
1 2 3 4 5 6 7 8 def trailingZeroes(n): count = 0 while n > 0: n //= 5 count += n return count
题目80:Excel 表列名称
问题描述:给定一个正整数 columnNumber,返回它在 Excel 表中相对应的列名称。例如 1 -> A,28 -> AB,701 -> ZY。
解题思路:这本质是一个 26 进制转换问题,但需要注意 Excel 列名称是从 1 开始的(没有 0)。每次将 columnNumber 减 1 后再对 26 取余,得到当前位的字符,然后更新 columnNumber //= 26,直到为 0。
Python 代码示例:
1 2 3 4 5 6 7 8 9 def convertToTitle(columnNumber): result = [] while columnNumber > 0: columnNumber -= 1 result.append(chr(columnNumber % 26 + ord('A'))) columnNumber //= 26 return ''.join(reversed(result))