需要多掌握解题套路
比赛地址
100157. 大于等于顺序前缀和的最小缺失整数
class Solution:def missingInteger(self, nums: List[int]) -> int:# Step 1: Find the longest consecutive prefixi = 0 for i in range(1, len(nums)):if nums[i] != nums[i - 1] + 1:breakelse:# Handle the case where the entire array is a consecutive prefixi += 1# Step 2: Calculate the sum of the longest consecutive prefixprefix_sum = sum(nums[:i])# Step 3: Find the smallest missing integer greater than the prefix summissing = prefix_sumwhile missing in nums:missing += 1return missing
100168. 使数组异或和等于 K 的最少操作次数
class Solution:def minOperations(self, nums: List[int], k: int) -> int:# Step 1: Calculate the XOR of all elements in numsm = 0for num in nums:m ^= num# Step 2: Count the number of different bits between m and kxor = m ^ kcount = 0while xor:count += xor & 1xor >>= 1return count
100159. 使 X 和 Y 相等的最少操作次数
class Solution:def minimumOperationsToMakeEqual(self, x: int, y: int) -> int:# Queue will contain pairs (current_value, operations_count)queue = deque([(x, 0)])visited = set() # To keep track of already visited valueswhile queue:current, operations = queue.popleft()# If we have reached the target, return the number of operationsif current == y:return operations# Ensure we do not visit the same number againif current in visited:continuevisited.add(current)# If current is divisible by 11, enqueue the divided resultif current % 11 == 0:queue.append((current // 11, operations + 1))# If current is divisible by 5, enqueue the divided resultif current % 5 == 0:queue.append((current // 5, operations + 1))# Always enqueue the results of adding or subtracting 1queue.append((current + 1, operations + 1))queue.append((current - 1, operations + 1))# If y is never reached, return -1 or some error valuereturn -1
100163. 统计强大整数的数目
函数
numberOfPowerfulInt
:
- 输入参数:整数
start
,finish
,limit
和字符串s
。- 返回值:区间
[start, finish]
内符合条件的数字数量。- 实现:调用
dfs
函数两次来计算不超过finish
和start - 1
的符合条件的数字数量,然后相减得到结果。数位 DP 函数
dfs
:
- 输入参数:当前处理的数位索引
i
,一个布尔值is_limit
表示当前是否受到上界t
的限制,以及当前考虑的数的字符串表示t
。- 返回值:在给定限制下,从当前位开始能构造出的符合条件的数字数量。
- 实现:
- 首先检查边界条件,当剩下的位数等于
s
的长度时,只能填入s
,并根据是否受限制判断是否可行。- 对于每一位,根据是否受限制和
limit
的值确定当前位的可能数字范围。- 递归地调用
dfs
来处理下一位,并累计所有可能性的总数。递归和缓存:
dfs
函数使用递归来处理每一位,通过@cache
装饰器对函数结果进行缓存,以避免重复计算相同状态的结果,从而提高性能。
总体而言,这个实现通过精确地处理每一位的可能性,并利用递归和函数缓存来有效地处理大范围的数据。这种方法在处理复杂的数位相关问题时非常有效,尤其是在涉及大数字时。
class Solution:def numberOfPowerfulInt(self, start: int, finish: int, limit: int, s: str) -> int:n = len(s)# 数位dp函数,使用缓存装饰器以优化性能@cachedef dfs(i, is_limit, t):# 如果剩余数字的长度小于后缀s的长度,则不可能构成有效数字if len(t) < n:return 0# 当剩余的位数等于后缀s的长度,只能填入sif len(t) - i == n:# 如果当前是受限状态,则检查t的剩余部分是否大于等于sif is_limit:return int(s <= t[i:])else:# 如果不受限,只有一种情况,即填入sreturn 1res = 0start = 0# 如果当前受限,则枚举的数字不能超过t的当前位数字if is_limit:end = int(t[i])else:end = 9# 枚举的数字还需受限于limitend = min(end, limit)# 枚举当前位可能的数字,并递归处理下一位for num in range(start, end+1):res += dfs(i+1, is_limit and num == int(t[i]), t)return res# 计算区间[start, finish]内符合条件的数字数量return dfs(0, True, str(finish)) - dfs(0, True, str(start-1))
is_limit and num == int(t[i])
:这个表达式决定了在下一次递归调用中,是否仍然受到上界t
的限制。
- 如果当前位
num
等于t
在位置i
的数字,并且之前的位置已经受到限制(is_limit
为True
),那么在下一位上仍然受到限制。- 如果
num
不等于t[i]
或之前的位置没有受到限制,那么在下一位上不再受到限制。
下面举例说明这个过程:
假设我们有 t = "5432"
,limit = 9
,并且当前我们在第二位(假设索引从 0 开始),即 i = 1
,之前的数位值是 5
,与 t[0]
相等,所以到目前为止我们是受限的(is_limit = True
)。现在我们要决定第二位 i = 1
的值。
如果我们选择
num = 4
(即等于t[1]
):
- 在下一次递归调用中,我们仍然受限于
t
,因为到目前为止构造出的数字仍然与t
的前缀相匹配。所以,is_limit
仍然为True
。如果我们选择
num = 3
(即小于t[1]
):
- 在这种情况下,我们已经偏离了
t
的对应位置。即使之前是受限的,现在我们可以认为后续的数位不再受到t
的限制。因此,在下一次递归调用中,is_limit
将变为False
。- 这意味着对于这个位置及后续位置上的数位,我们可以自由地选择任何不超过
limit
的数字,而不用担心超过t
。num > t[i]
的情况不会发生,在之前的判断中已经被排除了# 如果当前受限制(is_limit),则枚举的数字不能超过t的当前位数字 if is_limit:end = int(t[i]) else:end = 9