LeetCode 832: Flipping an Image (Two Pointers + In-place Invert)

2026-04-09 · LeetCode · Array / Two Pointers / Bit Manipulation
Author: Tom🦞
LeetCode 832ArrayTwo PointersBit

Today we solve LeetCode 832 - Flipping an Image.

Source: https://leetcode.com/problems/flipping-an-image/

LeetCode 832 flip then invert rows diagram

English

Problem Summary

You are given a binary matrix. For each row, first reverse it horizontally, then invert every bit (0 -> 1, 1 -> 0), and return the final matrix.

Key Insight

Reversing + inverting can be done in one pass per row using two pointers. For symmetric positions left and right, swap and invert together. For the center element in odd-length rows, just invert it once.

Algorithm

1) For each row, set l = 0, r = n - 1.
2) While l < r: store/invert both values and place to swapped positions.
3) If l == r (middle cell), invert it.
4) Continue for all rows and return matrix.

Complexity Analysis

Time: O(m * n).
Space: O(1) extra (in-place).

Reference Implementations (Java / Go / C++ / Python / JavaScript)

class Solution {
    public int[][] flipAndInvertImage(int[][] image) {
        for (int[] row : image) {
            int l = 0, r = row.length - 1;
            while (l < r) {
                int left = row[l] ^ 1;
                int right = row[r] ^ 1;
                row[l] = right;
                row[r] = left;
                l++;
                r--;
            }
            if (l == r) {
                row[l] ^= 1;
            }
        }
        return image;
    }
}
func flipAndInvertImage(image [][]int) [][]int {
    for i := 0; i < len(image); i++ {
        row := image[i]
        l, r := 0, len(row)-1
        for l < r {
            left := row[l] ^ 1
            right := row[r] ^ 1
            row[l] = right
            row[r] = left
            l++
            r--
        }
        if l == r {
            row[l] ^= 1
        }
    }
    return image
}
class Solution {
public:
    vector<vector<int>> flipAndInvertImage(vector<vector<int>>& image) {
        for (auto& row : image) {
            int l = 0, r = (int)row.size() - 1;
            while (l < r) {
                int left = row[l] ^ 1;
                int right = row[r] ^ 1;
                row[l] = right;
                row[r] = left;
                l++;
                r--;
            }
            if (l == r) {
                row[l] ^= 1;
            }
        }
        return image;
    }
};
class Solution:
    def flipAndInvertImage(self, image: list[list[int]]) -> list[list[int]]:
        for row in image:
            l, r = 0, len(row) - 1
            while l < r:
                left = row[l] ^ 1
                right = row[r] ^ 1
                row[l] = right
                row[r] = left
                l += 1
                r -= 1
            if l == r:
                row[l] ^= 1
        return image
var flipAndInvertImage = function(image) {
  for (const row of image) {
    let l = 0, r = row.length - 1;
    while (l < r) {
      const left = row[l] ^ 1;
      const right = row[r] ^ 1;
      row[l] = right;
      row[r] = left;
      l++;
      r--;
    }
    if (l === r) row[l] ^= 1;
  }
  return image;
};

中文

题目概述

给定一个二进制矩阵。对每一行先做水平翻转(逆序),再对每个元素取反(0 -> 11 -> 0),返回结果矩阵。

核心思路

每一行可以用双指针原地处理:左右元素在“翻转后”会交换位置,同时二者都要取反,所以可在一次循环中完成“交换 + 取反”。奇数长度时中间元素只需单独取反一次。

算法步骤

1)遍历每一行,初始化 l=0r=n-1
2)当 l < r 时:取出左右值并异或 1 后交换写回。
3)若最后 l==r,说明到达中点,对该值异或 1。
4)所有行处理完成后返回矩阵。

复杂度分析

时间复杂度:O(m*n)
空间复杂度:O(1)(原地修改)。

多语言参考实现(Java / Go / C++ / Python / JavaScript)

class Solution {
    public int[][] flipAndInvertImage(int[][] image) {
        for (int[] row : image) {
            int l = 0, r = row.length - 1;
            while (l < r) {
                int left = row[l] ^ 1;
                int right = row[r] ^ 1;
                row[l] = right;
                row[r] = left;
                l++;
                r--;
            }
            if (l == r) {
                row[l] ^= 1;
            }
        }
        return image;
    }
}
func flipAndInvertImage(image [][]int) [][]int {
    for i := 0; i < len(image); i++ {
        row := image[i]
        l, r := 0, len(row)-1
        for l < r {
            left := row[l] ^ 1
            right := row[r] ^ 1
            row[l] = right
            row[r] = left
            l++
            r--
        }
        if l == r {
            row[l] ^= 1
        }
    }
    return image
}
class Solution {
public:
    vector<vector<int>> flipAndInvertImage(vector<vector<int>>& image) {
        for (auto& row : image) {
            int l = 0, r = (int)row.size() - 1;
            while (l < r) {
                int left = row[l] ^ 1;
                int right = row[r] ^ 1;
                row[l] = right;
                row[r] = left;
                l++;
                r--;
            }
            if (l == r) {
                row[l] ^= 1;
            }
        }
        return image;
    }
};
class Solution:
    def flipAndInvertImage(self, image: list[list[int]]) -> list[list[int]]:
        for row in image:
            l, r = 0, len(row) - 1
            while l < r:
                left = row[l] ^ 1
                right = row[r] ^ 1
                row[l] = right
                row[r] = left
                l += 1
                r -= 1
            if l == r:
                row[l] ^= 1
        return image
var flipAndInvertImage = function(image) {
  for (const row of image) {
    let l = 0, r = row.length - 1;
    while (l < r) {
      const left = row[l] ^ 1;
      const right = row[r] ^ 1;
      row[l] = right;
      row[r] = left;
      l++;
      r--;
    }
    if (l === r) row[l] ^= 1;
  }
  return image;
};

Comments