复盘|第339场周赛
最长平衡子字符串
【暴力】数据范围较小,直接暴力穷举。
【双指针模拟】找到所有01串,其中平衡字符串的长度是min(pre, cur) * 2,用pre记录上一段连续字符的个数,用cur记录当前段连续字符的个数,在所有01串的末尾(分界线:字符串末尾或下一个字符不等于当前字符)更新pre和cur,如果是1就更新最大值。
转换二维数组
【哈希表模拟】观察到行数至多为nums中某个元素出现的最大次数,每行平铺一个数。
优化写法,用哈希表维护剩余次数,如果剩余次数为0,将x从cnt中删除。
老鼠和奶酪
【贪心】让老鼠1优先吃reward1[i] - reward2[i]最大的k个奶酪,剩下的给老鼠2吃。代码中需要对差值数组diff[i]排序。
最少翻转操作数
【平衡树 + BFS】 对于子数组[L,R]中的任意下标i,翻转后的下标是L+R-i(中心对称翻转,两个下标相加恒等于L+R)。那么当子数组向右滑动时,工和R都增加1,所以翻转后的下标会增加2;当子数组向左滑动时,L和R都减少1,所以翻转后的下标会减少2因此,i翻转后的所有位置组成了一个公差为2的等差数列(不考虑banned)。如果不考虑数组的边界,那么范围是[i-k+1, i+k-1]。如果i在数组左边界0附近,那么翻转时会受到数组左边界的约束,当子数组在最左边时,L=0,R=k-1,i翻转后是0+(k-1)-i=k-i-1,所以小于-i-1的点是无法翻转到的;如果i在数组右边界n-1附近,那么翻转时会受到数组右边界的约束,当子数组在最右边时,L=n-k,R=n-1,i翻转后是(n-k)+(n-1)-i=2n-k-i-1,所以大于2n-k-i-1的点是无法翻转到的。所以实际范围为max(i-k +1,k-i-1),min(i+k-1,2n-k-i-1)。用两棵平衡树分别维护不等于p也不在banned中的偶数下标和奇数下标。然后用BFS模拟。在对应的平衡树上,一边遍历翻转后的所有位置,一边把平衡树上的下标删除,加到队列中。这样可以避免重复访问已经访问过的节点。