复盘|第106场双周赛
判断一个数是否迷人
【模拟】按题意模拟,计算拼接后的数字中1-9的数量是否为1。
【打表】观察数字规律,合法n范围是[123, 329],进一步可以枚举所有三位数n,发现只有4个数满足条件。
找到最长的半重复子字符串
【滑动窗口】向右移动右指针统计相邻相同的情况的出现次数,如果次数大于1,需要不断向右移动左指针直到s[left] == s[left - 1]说明有一对相邻相同的字符的左边移到窗口之外了,此时次数变回1了,然后统计窗口大小。
移动机器人
【数学 + 排序 + 前缀和】由于最后是求距离之和,可以把所有机器人看成一样的,碰撞看作互相穿过对方。设d秒后机器人的位置数组为nums,将nums从小到大排序再计算所有机器人之间的两两距离之和。从小到大枚举nums[i],此时左边有i个数都不超过nums[i],那么nums[i]与左侧机器人的距离之和为(nums[i] - nums[0]) + (nums[i] - nums[1]) + .... + (nums[i] - nums[i - 1]) = i * nums[i] - (nums[0] + nums[1] + .. nums[i -1]),其中nums[0] + ...nums[i-1]是前缀和,可以一边遍历一边算。python之外的语言为了防止溢出需要在计算中取模。
找到矩阵中的好子集
【贪心 + 哈希表 + 位运算】如果是1行,全为0;如果是2行,不能有同一列都是1,与的结果是0;3/5行,不可能,因为⌊k/2⌋=⌊(k−1)/2⌋;4行,必须任意两行都至少都一列都是1,且不能是同一列,所有至少需要六列,而n至多是5,所有只可能是1或2行。将每一行转换成一个二进制数,用一个字典将二进制数映射到行号,然后尝试找到两个不相交的子集,这两个子集得到列和均不超过他们各自大小的一半。