复盘|第309场周赛
2399. 检查相同字母间的距离 https://leetcode.cn/problems/check-distances-between-same-letters/
【哈希表】统计每个字母的位置,遍历哈希表,判断每个字母的下标之差是否等于distance[i]。
2400. 恰好移动 k 步到达某一位置的方法数目 https://leetcode.cn/problems/number-of-ways-to-reach-a-position-after-exactly-k-steps/
【记忆化搜索】想到dp[i] [j]表示在i位置,走j步或剩j步,当前状态下的方案数。dp数组为了避免负数,可以写成记忆化搜索,dfs(x, left),x表示位置,left表示还剩余可走的步数,首先把edge case处理,当前方案数 = 往左走方案数 + 往右走的方案数,可以加几个剪枝,①距离 > k走不到 ②d与k奇偶性需一致。left == 0时表示已经走到终点,是一种方案。
【组合数学】推导:总共向右走r步,向左走l步,则r + l = k,r - l = m,r = (k + m) / 2, 向右方案数Comb(k, r),即在k步中选择r步的方案数。
2401. 最长优雅子数组 https://leetcode.cn/problems/longest-nice-subarray/
【滑动窗口】根据题意,要求子数组内每对元素与运算的结果均为0,即找到一个最长的区间,区间里每一个数的对应二进制位只能有一个1,因为如果有2个1,那么这两个位置对起来(1&1),结果就是1了,这题数据范围10^9,一共要用三十二个二进制位存,每个位上至多只能有一个1。技巧:当x&y已经是0了,可以tmp = x|y,后一个碰到的z直接 z&tmp 就行(因为或运算保留了xy里所有1)。代码中,用双指针维护滑动窗口,or_存滑动窗口内的或的结果,xor左指针元素,相当于弹出左指针元素。如果or _ & x不为0,则需要把左指针往右移(弹出左指针指向元素弹出)。同样,手写max会加速python。
2402. 会议室 III https://leetcode.cn/problems/meeting-rooms-iii/
【双堆模拟】 用两个小顶堆模拟:一个堆维护start_i时刻空闲的会议室的编号,另一个堆维护start_i时刻正在使用的会议室的结束时间和编号。