leetcode[1310]子数组异或查询 Python3实现(异或区间操作,备忘录)

# 有一个正整数数组 arr,现给你一个对应的查询数组 queries,其中 queries[i] = [Li, Ri]。 
# 
#  对于每个查询 i,请你计算从 Li 到 Ri 的 XOR 值(即 arr[Li] xor arr[Li+1] xor ... xor arr[Ri])作为
# 本次查询的结果。 
# 
#  并返回一个包含给定查询 queries 所有结果的数组。 
# 
#  
# 
#  示例 1: 
# 
#  输入:arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
# 输出:[2,7,14,8] 
# 解释:
# 数组中元素的二进制表示形式是:
# 1 = 0001 
# 3 = 0011 
# 4 = 0100 
# 8 = 1000 
# 查询的 XOR 值为:
# [0,1] = 1 xor 3 = 2 
# [1,2] = 3 xor 4 = 7 
# [0,3] = 1 xor 3 xor 4 xor 8 = 14 
# [3,3] = 8
#  
# 
#  示例 2: 
# 
#  输入:arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]]
# 输出:[8,0,4,4]
#  
# 
#  
# 
#  提示: 
# 
#  
#  1 <= arr.length <= 3 * 10^4 
#  1 <= arr[i] <= 10^9 
#  1 <= queries.length <= 3 * 10^4 
#  queries[i].length == 2 
#  0 <= queries[i][0] <= queries[i][1] < arr.length 
#  
#  Related Topics 位运算 
#  👍 69 👎 0

暴力计算,果断超时:

class Solution:
    def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
        ret = []
        for q in queries:
            ret.append(reduce(xor, arr[q[0] : q[1]+1]))
        return ret

用二维动态规划,依然超时:

class Solution:
    def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
        dp = [[0] * len(arr) for _ in range(len(arr))]
        for i in range(len(arr)):
            dp[i][i] = arr[i]

        for i in range(len(arr)):
            for j in range(i+1, len(arr)):
                dp[i][j] = dp[i][j-1] ^ arr[j]

        ret = []
        for q in queries:
            ret.append(dp[q[0]][q[1]])
        return ret

用dict建立重复结果的备忘录,终于勉强通过:

class Solution:
    def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
        ret = []
        memo = {}
        for q in queries:
            if (q[0], q[1]) not in memo.keys():
                ans = reduce(xor, arr[q[0]: q[1] + 1])
                memo[(q[0], q[1])] = ans
            ret.append(memo[(q[0], q[1])])
        return ret
执行用时:9072 ms, 在所有 Python3 提交中击败了5.77%的用户
内存消耗:29.4 MB, 在所有 Python3 提交中击败了8.97%的用户

最后参考官方题解,恍然大悟。
其实,动态规划的思路以及很接近了,只不过不需要记录所有dp[i][j]的异或结果,只需记录一维的memo[i](i表示前i个数的异或)的结果即可。因为:

dp[i][j] = memo[i-1] ^ memo[j]

用到了异或操作的结合律,以及相同值异或为0的结论。

最终代码:

class Solution:
    def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
        memo = [0] * (len(arr) + 1)
        for i in range(1, len(arr)+1):
            memo[i] = memo[i-1] ^ arr[i-1]
        ret = []
        for i, j in queries:
            ret.append(memo[i] ^ memo[j+1])
        return ret
执行耗时:424 ms,击败了50.00% 的Python3用户
内存消耗:29.4 MB,击败了14.10% 的Python3用户
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值