算法与数据结构:常见笔试题总结
文章目录
- 9.13 美团
- 9.20 京东
- 9.19 饿了么 01
- 9.19 饿了么 03
9.13 美团
- 奇偶性分析:一个数是奇数当且仅当它的二进制最低位为1。异或运算i⊕ai \oplus ai⊕a的最低位为1,意味着 i 和 a 的最低位必须不同(一个为0,一个为1)。
- 排列的性质:排列包含1到n的所有整数,每个数恰好出现一次。
- 必要条件:对于每个位置 i,i 和 a 的奇偶性必须相反。这意味着如果 i 是奇数,则 a 必须是偶数;如果 i 是偶数,则 a必须是奇数。
- 奇偶数量匹配:在1到n的整数中要满足条件,需要:
奇数位置(i为奇数)的数量必须等于偶数的个数
偶数位置(i为偶数)的数量必须等于奇数的个数 - 当 n为奇数时无解,输出 -1;当 n为偶数时存在解。
对于偶数 n,我们可以采用简单的配对策略:- 直接反转数组,此时奇数位置为偶数,偶数位置是奇数
- 将最后一个数字放到最前面,同样做到奇数位置为偶数,偶数位置是奇数。
T = int(input())for _ in range(T):n = int(input())if n % 2 == 1:print(-1)else:lis = list(range(1, n + 1))lis.reverse()print(*lis)
2
1
-1
2
2 1
9.20 京东
- 初始化:用一个数组
candy
保存每个小朋友的粽子数,初始都为1(保证至少一个) - 从左到右扫描:如果当前位置卡片是’+',说明下一个小朋友要比当前多,所以让
candy[i+1]= candy[i]+ 1
- 从右到左扫描:如果当前位置卡片是’-',说明下一个小朋友要比当前少,所以保证
candy[i]>= candy[i+1]+ 1
,用max
保证不破坏之前的约束。 - 计算答案:
candy[i]
加起来就是最后把所有小朋友的最少需要的粽子数量。
n = int(input())s = input()candy = [1]*(n+1)# 从左到右处理 '+'
for i in range(n):if s[i] == '+':candy[i+1] = candy[i] + 1# 从右到左处理 '-'
for j in range(n-1, -1, -1):if s[j] == '-':candy[j] = max(candy[j], candy[j+1] + 1)print(sum(candy))
9.19 饿了么 01
9.19 饿了么 03
通过分析最优的数组应该是0放在最中间,然后奇数放在0的右侧,偶数放在0的左侧,可现结果和杨辉三角有关,最终的结果可以从如下的规律得出。
实际上最终的答案为 杨辉三角 某一列的值,可以通过组合数得出。
1, 3, 7, 13, 22, 34, 50, 70, 95
每个数之间的差值有规律,分别是1x2,2x2,2x3,3x3,……
所以可以根据a[i+1] - a[i]
的规律直接得到整个数组。
T = int(input())ans = [0]*100000
for i in range(1, 100000):ans[i] = (i // 2)*(i // 2 + 1) if i % 2 == 0 else ((i+1)//2)**2ans[i] += ans[i-1]for _ in range(T):n = int(input())print(ans[n])res = []for j in range(n):res.append(j) if j % 2 == 0 else res.insert(0, j)print(*res) # 解包写法,可以借鉴,不用遍历数组。