📌 题目1:求两数之和
给定:
- 一个正整数数组
numbers - 一个目标整数
k
请你判断:是否存在两个不同位置的整数,使它们的和等于 k
📥 输入
numbers:整数数组(例如 [1, 5, 8, 1, 2])k:目标和(例如 13)
📤 输出
- 返回一个长度为 2 的数组索引,如: [i, j]
⚠️ 约束条件
- 不能使用同一个元素两次(i != j)
- 必须返回 索引(index),不是数值
- 若有多个解:
- 优先选择 较小的 i
- 若 i 相同,选择 较小的 j
- 如果不存在这样的两个数:返回 [0, 0]
解题
python
def find_sum_pair(numbers, k):
n = len(numbers)
for i in range(n):
for j in range(i + 1, n):
if numbers[i] + numbers[j] == k:
return [i, j]
return [0, 0]
现在调用:
python
numbers = [1, 5, 8, 1, 2]
k = 13
result = find_sum_pair(numbers, k)
print(result)
输出应该是
[1, 2]
解释:1是5在数组numbers里的索引,2是8在数组里的索引,两者相加等于输入参数k,所以函数返回一个[i,j]的索引。
核心逻辑拆解
我们可以把这个函数的工作流程看作是一个"地毯式搜索"的过程:
- 1.输入参数:它接收一个列表 numbers 和一个目标和 k。
- 2.双重循环嵌套:
- 外层循环 (i):固定第一个数字。
- 内层循环 (j):从第一个数字之后的每一个位置开始,寻找第二个数字。这样可以确保不会重复检查同一对组合,也不会自己加自己。
- 3.条件判断:检查 numbers[i] + numbers[j] == k 是否成立。
- 返回值:
- 成功:一旦找到符合条件的两个数,立即返回它们的索引下标 [i, j]。
- 失败:如果遍历完所有组合都没找到,则返回 [0, 0](这通常是一个占位符,表示未找到)。
解题(优化版本)
python
def find_sum_pair(numbers, k):
# 账本:key 是数字的值,value 是该数字的索引
hash_map = {}
for i, num in enumerate(numbers):
# 计算我们需要找的那个"另一半"
complement = k - num
# 检查"另一半"是否已经在账本里了
if complement in hash_map:
# 如果在,说明找到了,返回 [之前的索引, 当前索引]
return [hash_map[complement], i]
# 如果不在,就把当前数字和索引存入账本,留给后面的数字匹配
hash_map[num] = i
# 如果遍历完都没找到,返回空列表或自定义的失败标识
return []
📌 题目2:解谜游戏-自动移除所有的方块不可碰撞
1. 游戏背景与规则
- 场景:你在木工坊里为孙辈们制作木制玩具。你设计了一系列滑块谜题,并希望自动化求解过程。
- 核心玩法:
- 谜题是一个网格,上面放置了各种形状的木块(Blocks)。
- 目标是将所有木块一个接一个地移出游戏区域,且移动过程中不能发生碰撞。
- 移动方式:每个木块只能向右移动,直到它完全离开网格。
- 选择权:如果同时有多个木块可以移出,你可以任选其一。
2. 实现细节 (solve 函数)
你需要实现一个函数 solve(width, height, nb_blocks, grid),该函数在每一轮游戏时执行,并返回下一个要移动的木块编号。
输入参数说明:
- width:网格的宽度(单元格数量)。
- height:网格的高度(单元格数量)。
- nb_blocks:初始状态下木块的总数。
- grid:一个包含 height 个元素的列表,每个元素是一个长度为 width 的字符串,代表网格的当前状态。
网格字符含义:
- . (点):代表空位。
- X (墙壁):放置在第一行、最后一行以及每行的第一个字符。墙壁不可移动,这意味着唯一的出口是在网格的右侧。
- 0 到 nb_blocks - 1 的数字:代表不同的木块。同一个数字可能出现在多个格子里,表示这是一个占据多个格子的单体木块。所有标有相同数字的单元格都是相连的。
3. 输出与胜利条件
- 输出数据:返回一个整数(0 到 nb_blocks - 1),代表你想要向右移出的那个木块的编号。
- 移动规则:木块一旦开始移动,就会一直向右滑动,直到完全离开网格,或者撞到另一个木块/墙壁。
- 胜利条件:当所有的木块都成功移出游戏区域时,获得胜利。题目保证至少存在一种可能的移除顺序。
解题
python
def solve(width, height, nb_blocks, grid):
# 找所有 block
blocks = set()
for row in grid:
for c in row:
if c.isdigit():
blocks.add(c)
# 一个一个试
for b in sorted(blocks):
ok = True
for i in range(height):
for j in range(width):
if grid[i][j] == b:
# 看右边
k = j + 1
while k < width:
if grid[i][k] not in ('.', b):
ok = False
break
k += 1
if not ok:
break
if not ok:
break
if ok:
return int(b)
return 0
思路
- 1.找所有数字(block)
- 扫描所有方块 (blocks),代码首先遍历整个 grid,把所有数字(代表不同的方块或物体)存入一个集合 blocks 中。它关心的对象是那些带有数字编号的方块。
- 2.一个一个试
- 通过 sorted(blocks),它从小到大依次检查每一个方块 b。一旦找到第一个符合条件的方块,就立即返回它的编号。
- 3.谁右边是空的 → 返回谁
- 这是代码最关键的部分。对于当前选中的方块 b:
- 程序会找到网格中所有标记为 b 的坐标。
- 视野检查:从方块 b 的每一个点开始,向其右侧(即列坐标增加的方向)进行扫描。
- 阻碍判定:
- 如果右侧是空格(.)或者是方块 b 自身的一部分,则认为路径通畅。
- 如果遇到了任何其他编号的方块(既不是点也不是自己),说明被挡住了,设置 ok = False。
这个解法很直观,但不是特别高效。