复盘|第98场双周赛
替换一个数字后的最大差值
【贪心】O(log n) 做法,找到左边第一个不是9的数位,把他换成9,这样一定是最大的。最小值是最左边的数直接替换成0.
修改两个元素的最小分数
【脑筋急转弯】从小到大排序后,三种情况可能达到最大得分:修改最大的两个数、修改最小的两个数,修改最小数的和最大的数。
最小无法得到的或值
【哈希表 + 枚举】直接暴力枚举,但不是枚举所有数,而只需要枚举2的幂次,因为或运算只能把二进制位的0变成1而1没法变成0,所以如果2^k是“可表达”的,那么2^k一定在nums中。对于所有0≤i<k,2^i都在nums中存在,那么1到2^k - 1都是“可表达”的,答案就是最小的,不存在于nums中的2的幂次。
压行版
进阶版:Lowbit优化,不用哈希表,用一个数mask记录nums中是2的幂次的数。判断一个数是2的幂次 x & (x - 1) = 0;找一个二进制数最右的1: x & (~x + 1) 即 x & (-x)
常用lowbit算法 x >> k & 1 求x的第k位数字 x & -x = x & (~x + 1) 保留x最右边的1,其余位置置0 x & (x - 1) 消除x最右边的1(最右边0变1),其余不变 x | (x + 1) 消除x最右边的0(最右边1变0),其余不变
更新数组后处理求和查询
【暴力】纯暴力会超时,用java的BitSet优化常数.
【线段树】线段树的用途:一个数组,更新一个子数组的值(都加上一个数,把子数组内元素取反……);查询一个子数组的值(求和、求最大值)。线段树两大思想:挑选O(n)个特殊区间,是的任意一个区间可拆分为O(logn)个特殊区间,O(n) ≤ 4n;lazy(延迟)更新:用一个数组维护每个区间需要更新的值,如果这个值=0表示不需要更新,!=0表示需要更新。如果后面又来了一个更新破坏了有lazy tag的区间,那么这个区间就得继续递归更新。
【位运算】