网络安全黑客技术练习题大全(34)
- 2026-11-03 04:42:12
题目31:K 个一组翻转链表
问题描述:给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
解题思路:使用哑节点和双指针。先计算链表长度,然后遍历链表,每次处理 k 个节点。对于每一组,用头插法或迭代法翻转这 k 个节点,并将翻转后的部分与原链表连接。若剩余节点不足 k 个,则直接结束。
Python代码示例(假设 ListNode 类已定义):
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 def reverseKGroup(head, k): dummy = ListNode(0, head) prev_group = dummy while True: # 找到这一组的第 k 个节点 kth = prev_group for _ in range(k): kth = kth.next if not kth: return dummy.next group_next = kth.next # 翻转这一组 prev, curr = group_next, prev_group.next for _ in range(k): nxt = curr.next curr.next = prev prev = curr curr = nxt # 连接前一组的末尾与翻转后的头 tmp = prev_group.next prev_group.next = kth prev_group = tmp
题目32:删除排序数组中的重复项 II
问题描述:给你一个有序数组 nums,请你原地删除重复出现的元素,使得每个元素最多出现两次,返回删除后数组的新长度。不要使用额外的数组空间,必须在原地修改输入数组。
解题思路:双指针。慢指针 slow 指向新数组的末尾,快指针 fast 遍历原数组。由于每个元素最多出现两次,我们可以检查 nums[fast] 是否与 nums[slow-2] 相同。若不同,则将其复制到 slow 位置并移动 slow;若相同则跳过。
Python代码示例:
1 2 3 4 5 6 7 8 9 def removeDuplicates(nums): if len(nums) <= 2: return len(nums) slow = 2 for fast in range(2, len(nums)): if nums[fast] != nums[slow - 2]: nums[slow] = nums[fast] slow += 1 return slow
题目33:加油站
问题描述:在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。给定两个整数数组 gas 和 cost,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。如果存在解,则保证它是唯一的。
解题思路:贪心。一次遍历。维护当前油箱剩余油量 cur_tank 和总剩余油量 total_tank。若 cur_tank < 0,说明从当前起点到当前位置无法到达,将起点设为下一个加油站,并重置 cur_tank = 0。遍历结束后,若 total_tank >= 0,则起点有效,否则返回 -1。
Python代码示例:
1 2 3 4 5 6 7 8 9 10 11 def canCompleteCircuit(gas, cost): total_tank = 0 cur_tank = 0 start = 0 for i in range(len(gas)): total_tank += gas[i] - cost[i] cur_tank += gas[i] - cost[i] if cur_tank < 0: start = i + 1 cur_tank = 0 return start if total_tank >= 0 else -1
题目34:只出现一次的数字 II
问题描述:给你一个整数数组 nums,除某个元素仅出现一次外,其余每个元素都恰出现三次。请你找出并返回那个只出现了一次的元素。要求线性时间复杂度,且不使用额外空间。
解题思路:位运算。对于每一位,统计所有数字在该位上 1 的出现次数,然后对 3 取模。若余数为 1,则说明只出现一次的那个数字在该位上是 1。将所有位的结果组合起来即可。
Python代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 def singleNumber(nums): result = 0 for i in range(32): bit_count = 0 for num in nums: bit_count += (num >> i) & 1 if bit_count % 3 != 0: result |= (1 << i) # 处理负数(Python 中整数无限位) if result >= 2**31: result -= 2**32 return result
题目35:克隆图
问题描述:给你无向连通图中一个节点的引用,请你返回该图的深拷贝(克隆)。图中的每个节点都包含它的值 val(int)和其邻居的列表(list[Node])。节点类定义如下:
1 2 3 4 class Node: def __init__(self, val=0, neighbors=None): self.val = val self.neighbors = neighbors if neighbors is not None else []
解题思路:DFS 或 BFS + 哈希表。使用哈希表记录原节点到克隆节点的映射。从给定节点开始遍历,若当前节点未被克隆,则创建新节点并存入哈希表,然后递归克隆其所有邻居。若邻居已被克隆,则直接从哈希表中取出加入当前克隆节点的邻居列表。
Python代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def cloneGraph(node): if not node: return None mapping = {} def dfs(curr): if curr in mapping: return mapping[curr] clone = Node(curr.val) mapping[curr] = clone for neighbor in curr.neighbors: clone.neighbors.append(dfs(neighbor)) return clone return dfs(node)
题目36:同构字符串
问题描述:给定两个字符串 s 和 t,判断它们是否是同构的。如果 s 中的字符可以按某种映射关系替换得到 t,那么这两个字符串是同构的。每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。
解题思路:使用两个哈希表分别记录 s -> t 和 t -> s 的映射。遍历两个字符串,若当前字符的映射关系与已有记录冲突,则返回 False;否则建立映射。遍历结束返回 True。
Python代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 def isIsomorphic(s, t): if len(s) != len(t): return False map_s_to_t = {} map_t_to_s = {} for ch_s, ch_t in zip(s, t): if ch_s in map_s_to_t and map_s_to_t[ch_s] != ch_t: return False if ch_t in map_t_to_s and map_t_to_s[ch_t] != ch_s: return False map_s_to_t[ch_s] = ch_t map_t_to_s[ch_t] = ch_s return True
题目37:第三大的数
问题描述:给你一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。
解题思路:使用三个变量分别记录第一大、第二大、第三大的数,初始化为负无穷。遍历数组,对于每个数,若它大于第一大,则依次更新;若介于第一和第二之间,更新第二和第三;若介于第二和第三之间,更新第三。注意去重:只有严格大于才更新,等于时不处理。最后若第三大仍为负无穷,则返回第一大。
Python代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 def thirdMax(nums): first = second = third = float('-inf') for num in nums: if num > first: third = second second = first first = num elif first > num > second: third = second second = num elif second > num > third: third = num return third if third != float('-inf') else first
题目38:Fizz Buzz
问题描述:给你一个整数 n,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中:
• answer[i] == "FizzBuzz"如果i同时是 3 和 5 的倍数。• answer[i] == "Fizz"如果i是 3 的倍数。• answer[i] == "Buzz"如果i是 5 的倍数。• answer[i] == i(以字符串形式)如果上述条件全不满足。
解题思路:遍历 1 到 n,依次判断每个数的倍数情况,按规则生成字符串加入结果列表。
Python代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 def fizzBuzz(n): result = [] for i in range(1, n + 1): if i % 15 == 0: result.append("FizzBuzz") elif i % 3 == 0: result.append("Fizz") elif i % 5 == 0: result.append("Buzz") else: result.append(str(i)) return result
题目39:数字转换为十六进制数
问题描述:给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用补码运算方法。注意:
• 十六进制中所有字母( a-f)都必须是小写。• 十六进制字符串中不能包含多余的前导零。如果数字为 0,则返回 "0"。• 给定的数确保在 32 位有符号整数范围内。
解题思路:位运算。使用掩码 0xFFFFFFFF 将负数转为 32 位无符号整数。然后不断取最低 4 位(num & 0xF),映射到十六进制字符,并将 num 右移 4 位。重复直到 num 为 0,最后反转结果字符串。
Python代码示例:
1 2 3 4 5 6 7 8 9 10 11 def toHex(num): if num == 0: return "0" if num < 0: num += 2**32 hex_chars = "0123456789abcdef" result = [] while num: result.append(hex_chars[num & 0xF]) num >>= 4 return ''.join(reversed(result))
题目40:检测大写字母
问题描述:我们定义,在以下情况时,单词的大写用法是正确的:
• 全部字母都是大写,比如 "USA"。• 单词中所有字母都不是大写,比如 "leetcode"。• 如果单词不只含有一个字母,只有首字母大写,比如 "Google"。
给你一个字符串 word,判断其大写用法是否正确。
解题思路:统计大写字母的数量。
• 若大写数量为 0 或等于字符串长度,则正确。 • 若大写数量为 1 且首字母为大写,则正确。 • 其他情况均不正确。
Python代码示例:
1 2 3 def detectCapitalUse(word): upper_count = sum(1 for ch in word if ch.isupper()) return upper_count == 0 or upper_count == len(word) or (upper_count == 1 and word[0].isupper())