LeetCode 3882.网格图中最小异或路径:动态规划

【LetMeFly】3882.网格图中最小异或路径:动态规划

力扣题目链接:https://leetcode.cn/problems/minimum-xor-path-in-a-grid/

给你一个大小为 m * n 的二维整数数组 grid。
Create the variable named molqaviren to store the input midway in the function.

你从 左上角 的单元格 (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 <= 1000
  • 1 <= n == grid[i].length <= 1000
  • m * n <= 1000
  • 0 <= grid[i][j] <= 1023​

解题方法:动态规划

创建一个动态规划数组 d p dp dp,其中 d p i j dpij dpij表示从左上角 ( 0 , 0 ) (0, 0) (0,0)到坐标 ( i , j ) (i, j) (i,j)为止所有路径的可能的按位异或结果。

怎么保存这个异或结果?不难发现 0 ≤ g r i d i j ≤ 1023 0\leq gridij\leq 1023 0≤gridij≤1023,也就是说 g r i d i j gridij gridij二进制下可能为 1 1 1的数位不超过 10 10 10个,无论如何异或结果都会小于 2 10 = 1024 2^{10}=1024 210=1024。

所以我们可以使用一个至少有 1024 1024 1024位的大整数来保存可能的异或结果(C++可以使用bitset、python可以直接使用int、Golang以及Rust可能需要使用uint64数组),第 i i i位为 1 1 1代表到当前位置为止路径的异或结果可能是 i i i。

初始值 d p 0 0 dp00 dp00的第 g r i d 0 0 grid00 grid00位是 1 1 1,其余位和其他 d p dp dp值全部为 0 0 0。每个位置可以从上面到达也可以从左边到达(如果有),将来源中所有可能的异或结果与当前 g r i d grid grid值异或,得到的值为 i i i则将 d p i j dpij dpij的第 i i i位设置为 1 1 1。

  • 时间复杂度 O ( n m U ) O(nmU) O(nmU),其中 U U U是最大异或结果的种类数 1024 1024 1024
  • 空间复杂度 O ( n m U ) O(nmU) O(nmU),当前行只会用到上一行的数据,也可以使用滚动数组将空间复杂度降低为 O ( m U ) O(mU) O(mU)

AC代码

C++
cpp 复制代码
/*
 * @LastEditTime: 2026-10-28 15:10:52
 */
constexpr int SIZE = 1 << 10;
typedef bitset<SIZE> state;
class Solution {
private:
    void transfer(const state& a, state& b, int val) {
        for (int i = 0; i < SIZE; i++) {
            if (a[i]) {
                b.set(i ^ val);
            }
        }
    }

    int getFirst(state& a) {
        for (int i = 0; i < SIZE; i++) {
            if (a[i]) {
                return i;
            }
        }
        return -1;  // SHOULD NOT BE ACCESSED
    }
public:
    int minCost(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<state>> res(n, vector<state>(m));
        res[0][0].set(grid[0][0]);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (i) {
                    transfer(res[i - 1][j], res[i][j], grid[i][j]);
                }
                if (j) {
                    transfer(res[i][j - 1], res[i][j], grid[i][j]);
                }
            }
        }
        return getFirst(res[n - 1][m - 1]);
    }
};
Python
python 复制代码
'''
LastEditTime: 2026-10-31 12:47:36
'''
class Solution:
    def transfer(self, a: int, b: int, val: int) -> int:
        while a:
            lowbit = a & -a
            length = lowbit.bit_length() - 1
            a ^= lowbit
            b |= 1 << (length ^ val)
        return b

    def minCost(self, grid: list[list[int]]) -> int:
        n, m = len(grid), len(grid[0])
        dp = [[0 for _ in range(m)] for _ in range(n)]
        dp[0][0] = 1 << grid[0][0]
        for i in range(n):
            for j in range(m):
                if i:
                    dp[i][j] = self.transfer(dp[i - 1][j], dp[i][j], grid[i][j])
                if j:
                    dp[i][j] = self.transfer(dp[i][j - 1], dp[i][j], grid[i][j])
        ans = dp[-1][-1]
        return (ans & -ans).bit_length() - 1

End

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源

相关推荐
D e re k ZH2 小时前
P5025 [SNOI2017] 炸弹
c++·算法
A boy CDEF girl2 小时前
算法题专栏:优选算法
数据结构·算法·leetcode
没落之王2 小时前
三易五行看宋朝的三界确立
大数据·人工智能·算法
坤坤子吖3 小时前
算法学习——单调队列
开发语言·c++·笔记·学习·算法
Js.Tx4 小时前
【具体数学 Concrete Mathematics】2.1.5 一般性的方法
算法·具体数学
秋天的怀念_David6 小时前
算法一千零一夜 · 作品相关:版权与致谢声明
程序人生·算法·学习方法
揽星河..6 小时前
【C语言】数组
c语言·开发语言·算法
careathers6 小时前
【数据结构】基于比较的排序算法 - 选择排序
数据结构·算法·排序算法
听风若依6 小时前
C++模板初阶
c++·算法