2.位运算——按位或模板

声明:模板来自于灵茶山艾府的个人空间-灵茶山艾府个人主页-哔哩哔哩视频 (bilibili.com)灵神,在此进行总结学习。

问题:898. 子数组按位或操作 - 力扣(LeetCode)计算子数组按位或运算之后,统计不同结果的个数。

分析:按位或运算有两个显著特点,一个数与其他数按位或的结果中一的个数要么不变要么加一;左端点相同时,遍历右端点按位或时存在两个右端点计算结果一致,说明中间数也会得出相同结果,因此可以原地去重。

本题使用map统计结果,ors计算并保存去重结果。反向遍历nums数组,ors中第一个位置保存m个元素按位或结果,第二个位置保存m-1个元素按位或结果,以此类推。然后进行原地去重,k代表保存不重复的运算结果的右端点(从0开始),我们需要依次比较ors中其余元素(因此使用ors[1:])是否重复,不重复则计数,并将他保存在k+1的位置。去重完毕之后,切片,保留k个不重复元素。

func subarrayBitwiseORs(nums []int) int {
    n := len(nums)
	ors:=make([]int,0)
    mp:=make(map[int]int)
	for i := n - 1; i >= 0; i-- {
		num := nums[i]
		ors = append(ors, 0)
		ors[0] |= num
        mp[ors[0]]++
		k := 0
		for _, p := range ors[1:] {
			p |= num
			if ors[k] != p {
                mp[p]++
				k++
				ors[k] = p
			}
		}
		ors = ors[:k+1]
	}
	return len(mp)
}

100271. 或值至少为 K 的最短子数组 II - 力扣(LeetCode)也是同样的思路

func minimumSubarrayLength(nums []int, k int) int {
	ans := math.MaxInt
	type pair struct{ or, left int }
	ors := []pair{} 
	for i, x := range nums {
		ors = append(ors, pair{0, i})
		ors[0].or |= x
		j := 0
		for _, p := range ors[1:] {
			p.or |= x
			if ors[j].or == p.or {
				ors[j].left = p.left 
			} else {
				j++
				ors[j] = p
			}
		}
		ors = ors[:j+1] 
		for len(ors) > 0 && ors[0].or >= k {
			ans = min(ans, i-ors[0].left+1)
			ors = ors[1:]
		}
	}
	if ans == math.MaxInt {
		return -1
	}
	return ans
}

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值