每日一题(202502)
0201 81. 搜索旋转排序数组 II
题目大意
给定一个旋转排序数组 nums
和一个目标值 target
,判断目标值是否存在于数组中。需要尽可能减少操作步骤。
解题思路
- 旋转数组特点:旋转后数组分为两部分,其中一部分是有序的。
- 使用二分查找:
- 判断左半部分是否有序,如果有序,判断目标值是否在这部分。
- 否则,判断右半部分是否有序,并进行类似操作。
- 处理重复元素:如果
nums[left] == nums[mid] == nums[right]
,无法确定哪部分有序,直接移动指针。
代码实现
class Solution:
def search(self, nums: List[int], target: int) -> bool:
if not nums:
return False
n = len(nums)
if n == 1:
return nums[0] == target
l, r = 0, n - 1
while l <= r:
mid = l + r >> 1
if nums[mid] == target:
return True
if nums[l] == nums[mid] and nums[mid] == nums[r]:
l += 1
r -= 1
elif nums[l] <= nums[mid]:
if nums[l] <= target < nums[mid]:
r = mid - 1
else:
l = mid + 1
else:
if nums[mid] < target <= nums[n - 1]:
l = mid + 1
else:
r = mid - 1
return False
0202 MarsCode 每日一题 红色格子染色方案数计算
1. 题目大意
有一个长度为 n
的格子,一部分已染红,剩余格子未染色。通过特定的规则(红色格子可以染色左右邻居),我们需要计算将所有格子染红的不同染色顺序。最终返回结果对 10^9 + 7
取模。
2. 解题思路
- 状态表示:使用一个整数来表示当前状态。每个格子是红色(1)还是未染色(0),用二进制表示。
- 状态转移:从每个红色格子出发,尝试向左右邻居染色。生成新状态并更新方案数。
- 广度优先搜索(BFS):从初始状态出发,使用队列逐步遍历所有可能的状态,并计算染色方案数。
- 动态规划:通过字典
f
记录每个状态的方案数,避免重复计算。
from collections import defaultdict, deque
mod = int(1e9) + 7
def solution(n, s):
initial = int(s, 2)
end = (1 << n) - 1
vis = defaultdict(bool)
q = deque([initial])
f = defaultdict(int)
f[initial] = 1
while q:
cur = q.popleft()
if vis[cur]:
continue
vis[cur] = True
for i in range(n):
if (cur >> i) & 1 == 0:
if (i - 1 >= 0 and (( cur >> (i - 1) ) & 1)) or (i + 1 <= n - 1 and (( cur >> (i + 1) ) & 1)):
nx = cur | (1 << i)
f[nx] = (f[nx] + f[cur]) % mod
q.append(nx)
return f[end]
# 测试样例
if __name__ == '__main__':
print(solution(5, "00101") == 3) # 3种方式
print(solution(6, "100001") == 8) # 8种方式
print(solution(7, "0001000") == 20) # 20种方式