复盘|第332场周赛
找出数组的串联值
【双指针 + 模拟】用数位的写法,O(1)空间。用i、j两个指针。
统计公平数对的数目
【二分】lower ≤ nums[i] + nums[j] ≤ upper,同时减 nums[j], lower - nums[j] ≤ nums[i] ≤ upper - nums[j],如果数组是有序的,则可以二分,对于每个nums[j],答案加上[lower - nums[j], upper-nums[j]] 这个范围的数字数量。(≤ upper - nums[j]的个数是>upper - nums[j]的第一个数的下标;<lower - nums[j]的数的个数是≥lower - nums[j的第一个数的下标])
子字符串异或查询
【预处理 + 枚举】题中val ^ first_i = second_i,两边^first_i得到val ^ first ^ first= second ^ first,题意就是找每个询问有多少个val = first ^ second。题中范围0≤first_i, second_i≤1e9,所以first_i^second_i<2**30。可以预处理是所有长度不超过30的字串,可以用哈希表记录每个二进制数对应的left和right。二进制的01拼接可以“×2+”,如10B = 1B × 2; ord(s[r]) - ord('0')相当于ord(s[r]) & 1)。[时间复杂度O(30n+q)]
最少得分子序列
【前后缀分解 + 双指针】删的越多剩下的越可能是s的子序列,所以就考虑删t的字串。删完字串后,剩下的部分是t的一个前缀和后缀。假设前缀匹配的是s的前缀s[:i],后缀匹配的是s的一个后缀s[i:](子序列匹配),则可以枚举i,分别计算能够与s[:i]和s[i:]匹配的t的最长前缀和最长后缀,要删除字串的最小值 = min(s[:i]对应的 t 的最长前缀的结束下标 - s[i:]对应的 t 的最长后缀的开始下标 - 1)。