Easy

题目描述

给定一个 n x n 的二进制矩阵 image,先 水平 翻转图像,然后 反转 图像并返回 结果

水平翻转图片就是将图片的每一行都进行翻转,即逆序。

  • 例如,水平翻转 [1,1,0] 的结果是 [0,1,1]

反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。

  • 例如,反转 [0,1,1] 的结果是 [1,0,0]

示例 1:

输入:image = [[1,1,0],[1,0,1],[0,0,0]]
输出:[[1,0,0],[0,1,0],[1,1,1]]
解释:首先翻转每一行: [[0,1,1],[1,0,1],[0,0,0]];
     然后反转图片: [[1,0,0],[0,1,0],[1,1,1]]

示例 2:

输入:image = [[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]]
输出:[[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]
解释:首先翻转每一行: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]];
     然后反转图片: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]

提示:

  • n == image.length
  • n == image[i].length
  • 1 <= n <= 20
  • images[i][j]01

解题思路

这道题需要我们对二进制矩阵进行两个操作:水平翻转(反转行)和反转值(0变1,1变0)。

基本思路:

  1. 两步法:先水平翻转每一行,再反转每个元素的值
  2. 一步法(推荐):利用双指针同时完成翻转和反转操作

一步法的核心思想: 对于每一行,使用双指针 leftright 分别指向行的两端。我们需要:

  • 交换 image[i][left]image[i][right]
  • 同时反转这两个位置的值

关键观察:image[i][left] == image[i][right] 时,交换后两个位置的值相同,反转后也相同,所以直接反转即可。 当 image[i][left] != image[i][right] 时,交换后再反转,相当于保持原值不变。

这样我们可以用一个简单的规则:如果两端的值相等,就反转;如果不相等,就保持原值。

代码实现

class Solution {
public:
    vector<vector<int>> flipAndInvertImage(vector<vector<int>>& image) {
        int n = image.size();
        for (int i = 0; i < n; i++) {
            int left = 0, right = n - 1;
            while (left <= right) {
                if (image[i][left] == image[i][right]) {
                    image[i][left] = 1 - image[i][left];
                    image[i][right] = 1 - image[i][right];
                }
                left++;
                right--;
            }
        }
        return image;
    }
};
class Solution:
    def flipAndInvertImage(self, image: List[List[int]]) -> List[List[int]]:
        n = len(image)
        for i in range(n):
            left, right = 0, n - 1
            while left <= right:
                if image[i][left] == image[i][right]:
                    image[i][left] = 1 - image[i][left]
                    image[i][right] = 1 - image[i][right]
                left += 1
                right -= 1
        return image
public class Solution {
    public int[][] FlipAndInvertImage(int[][] image) {
        int n = image.Length;
        for (int i = 0; i < n; i++) {
            int left = 0, right = n - 1;
            while (left <= right) {
                if (image[i][left] == image[i][right]) {
                    image[i][left] = 1 - image[i][left];
                    image[i][right] = 1 - image[i][right];
                }
                left++;
                right--;
            }
        }
        return image;
    }
}
/**
 * @param {number[][]} image
 * @return {number[][]}
 */
var flipAndInvertImage = function(image) {
    return image.map(row => row.reverse().map(pixel => 1 - pixel));
};

复杂度分析

复杂度类型说明
时间复杂度O(n²)需要遍历所有元素,每个元素访问一次
空间复杂度O(1)只使用常数额外空间,原地修改数组