基础算法-logTrick LeetCode-3171. 找到按位或最接近 K 的子数组 2163分

class Solution:
    def minimumDifference(self, nums: List[int], k: int) -> int:
        """
        核心思路:
    
        1. **动态维护子数组的按位或结果**:
           - 使用动态编程的方法,跟踪以每个元素结尾的所有可能子数组的按位或结果。
           - 对于每个新元素,更新现有的按位或结果,并将当前元素本身作为一个新的子数组。
           - 通过这种方式,避免了显式地枚举所有可能的子数组,优化了计算效率。
    
        2. **记录按位或结果的频次**:
           - 利用 defaultdict 来统计每个按位或结果出现的次数。
           - 这样可以快速查询每个按位或结果,并计算其与 k 的差值。
    
        3. **寻找最小差值**:
           - 遍历所有记录的按位或结果,计算它们与 k 的绝对差。
           - 返回最小的绝对差作为最终结果。
        """
        def logTrick(nums: List[int], op):
            res = defaultdict(int)
            dp = []
            for pos, cur in enumerate(nums):
                for v in dp:
                    v[2] = op(v[2], cur)
                dp.append([pos, pos + 1, cur])

                ptr = 0
                for v in dp[1:]:
                    if dp[ptr][2] != v[2]:
                        ptr += 1
                        dp[ptr] = v
                    else:
                        dp[ptr][1] = v[1]
                dp = dp[: ptr + 1]

                for v in dp:
                    res[v[2]] += v[1] - v[0]

            return res

        res = logTrick(nums, or_)
        ans = float('inf')
        for x in res:
            ans = min(ans, abs(k - x))
        return ans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值