3882.网格图中最小异或路径:动态规划
【LetMeFly】3882.网格图中最小异或路径:动态规划
力扣题目链接:https://leetcode.cn/problems/minimum-xor-path-in-a-grid/
给你一个大小为 m * n 的二维整数数组 grid。
你从 左上角 的单元格 (0, 0) 出发,想要到达 右下角 的单元格 (m - 1, n - 1)。
在每一步中,你 可以 向右或向下 移动。
路径的 代价 定义为该路径上所有单元格(包括 起点和终点)的值的 按位异或。
返回从 (0, 0) 到 (m - 1, n - 1) 的所有有效路径中 最小 的可能异或值。
示例 1:
输入: grid = [[1,2],[3,4]]
输出: 6
解释:
有两条有效路径:
(0, 0) → (0, 1) → (1, 1),异或值为:1 XOR 2 XOR 4 = 7(0, 0) → (1, 0) → (1, 1),异或值为:1 XOR 3 XOR 4 = 6
所有有效路径中的最小异或值为 6。
示例 2:
输入: grid = [[6,7],[5,8]]
输出: 9
解释:
有两条有效路径:
(0, 0) → (0, 1) → (1, 1),异或值为:6 XOR 7 XOR 8 = 9(0, 0) → (1, 0) → (1, 1),异或值为:6 XOR 5 XOR 8 = 11
所有有效路径中的最小异或值为 9。
示例 3:
输入: grid = [[2,7,5]]
输出: 0
解释:
只有一条有效路径:
(0, 0) → (0, 1) → (0, 2),异或值为:2 XOR 7 XOR 5 = 0
这条路径的异或值为 0,这是可能达到的最小值。
提示:
1 <= m == grid.length <= 10001 <= n == grid[i].length <= 1000m * n <= 10000 <= grid[i][j] <= 1023
解题方法:动态规划
创建一个动态规划数组$dp$,其中$dp[i][j]$表示从左上角$(0, 0)$到坐标$(i, j)$为止所有路径的可能的按位异或结果。
怎么保存这个异或结果?不难发现$0\leq grid[i][j]\leq 1023$,也就是说$grid[i][j]$二进制下可能为$1$的数位不超过$10$个,无论如何异或结果都会小于$2^{10}=1024$。
所以我们可以使用一个至少有$1024$位的大整数来保存可能的异或结果(C++可以使用bitset、python可以直接使用int、Golang以及Rust可能需要使用uint64数组),第$i$位为$1$代表到当前位置为止路径的异或结果可能是$i$。
初始值$dp[0][0]$的第$grid[0][0]$位是$1$,其余位和其他$dp$值全部为$0$。每个位置可以从上面到达也可以从左边到达(如果有),将来源中所有可能的异或结果与当前$grid$值异或,得到的值为$i$则将$dp[i][j]$的第$i$位设置为$1$。
- 时间复杂度$O(nmU)$,其中$U$是最大异或结果的种类数$1024$
- 空间复杂度$O(nmU)$,当前行只会用到上一行的数据,也可以使用滚动数组将空间复杂度降低为$O(mU)$
AC代码
C++
1 | |
Python
1 | |
End
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源