LeetCode刷题 - 高级算法扩展小结

一.位运算

一般基础的状态压缩就是将一行的状态压成一个数,这个数的二进制形式反映了这一行的情况。由于使用二进制来保存被压缩的状态,所以要用到神奇的二进制位运算操作,将一个十进制数转成二进制进行位运算操作再转回十进制数

总结

1.计算机有一套机制用二进制表示(正/负)整数/小数

2.平时我们写代码不用刻意写 ‘<<’ 或者 ‘>>’ 等移位运算符,因为编译器会自动做优化

如果要写,建议加括号

3.熟记真值表

4.XOR有很多性质,最重要的是:定义本身和交换律,结合律

其他性质可从定义和交换律,结合律推导出来

5.XOR的性质产生了很多等式,这些等式有时候可以写成状态转移方差,可以把原问题转换成dp问题

6.bit部分考的很少很少,甚至低于dp的范畴,主要用于状态压缩或者暴力解的时候方便穷尽所有的case,在contest里面常见

二.Reservoir Sampling / Rejection Sampling

水库抽样

public int getRandom() {
  int res = -1, count = 1;
  for (ListNode cur = head; cur != null; cur = cur.next)
    if (found_a_valid_case)
      if (random.nextInt(count++) == 0) res = cur.val;
  return res;
}

三.离线算法

什么叫在线算法?就是依次处理每一个query,对每一个query的计算,和之后的query无关,也不会用到之后的query信息(但可能也可以使用之前的query信息)

所以,在线算法,可以用来处理数据流。算法不需要一次性把所有的query都收集到再处理。大家也可以想象成:把这个算法直接部署到线上,尽管在线上可能又产生了很多新的query,也不影响,算法照常运行

离线算法则不同。离线算法需要把所有的信息都收集到,才能运行。处理当前query的计算过程,可能需要使用之后query的信息

总结

1.离线算法可以优化时间,缺点是需要知道所有的data,不能及时给每一个query答案,需要后台bash处理

2.这样做的核心在于,我们一边处理query,一边处理边,不是一次性的把所有的边都考虑进来,而是根据query的limit从小到大的限制,从小到大依次考虑边。注意,这个思路需要我们首先对整个query数组排序,之后再处理,所以需要收集到所有query信息以后再执行,它是一个离线算法

3.在线算法也可以实现类似的时间复杂度但是需要一些特殊算法,如树上倍增 + LCA

for (int i = 0, j = 0; i < N; i++) {
  int[] query = queries[i];
  while (j < M && edgeList[j][2] < queries[i][2]) //如果构造edge小于limit就创建
    dsu.union(edgeList[j][0],edgeList[j++][1]);
  res[queries[i][3]] = dsu.find(queries[i][0]) == dsu.find(queries[i][1]);
}

四.滚动哈希

考的不多,多为Hard题

public int search(String S, int L, int[] nums) {      //sliding window size = L
  long h = 0, aL = 1;
  for (int i = 0; i <L; i++) h = (h * a + nums[i]) % MOD;
  for (int i = 1; i <= L; i++) aL = (aL * a) % MOD;
  Set<Long> seen = new HashSet(List.of(h));
  for (int start = 1; start < n - L + 1; start++) {
    h = h * a;                                        //move window
    h = (h - nums[start - 1] * aL % MOD + MOD) % MOD; //remove last digit
    h = (h + nums[start + L - 1]) % MOD;              //input new digit
    if (!seen.add(h)) return start;
  }
  return -1;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值