题目
给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果。
水平翻转图片就是将图片的每一行都进行翻转,即逆序。例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, 1]。
反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。例如,反转 [0, 1, 1] 的结果是 [1, 0, 0]。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flipping-an-image
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的代码
class Solution {
public int[][] flipAndInvertImage(int[][] A) {
int len = A[0].length;
int temp;
for(int i=0; i<A.length; i++) {
for (int j=0; j<len/2+len%2; j++) {
temp = 1 - A[i][j];
A[i][j] = 1 - A[i][len-1-j];
A[i][len-1-j] = temp;
}
}
return A;
}
}
小结
说实话,很久没有正经做题,加上三四年没写过java,看完题有点局促。然后开始分析题目,数组内只含0和1,反转操作可以通过1-A[i][j]实现,翻转的操作从收尾对调考虑。
思路小坑:
- 收尾对掉,所以for循环应该自增到行长度的一半即可。
- 由于反转操作用的是拿1去减,结合首尾同时操作的原因,当行长度是偶数时和是奇数时处理情况应有不同(因为int类型/2后舍弃小数点)
官方提供的更优解
class Solution {
public int[][] flipAndInvertImage(int[][] A) {
int n = A.length;
for (int i = 0; i < n; i++) {
reverse(A[i]);
invert(A[i]);
}
return A;
}
private void reverse(int[] a) {
int begin = 0, end = a.length - 1, tmp = 0;
while (begin < end) {
tmp = a[begin];
a[begin] = a[end];
a[end] = tmp;
begin++;
end--;
}
}
private void invert(int[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
if (a[i] == 0) {
a[i] = 1;
} else {
a[i] = 0;
}
}
}
}
看完感觉真是瞎了心了,分明两个功能分开由子函数实现再按行遍历调用时间复杂度就很好,非要搞得代码短且“有技巧”的样子,意义到底在哪里?
可见黑猫白猫,抓到耗子就是好猫,往后看到题的时候应该如何考虑,值得思考。