作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/image-overlap/description/

题目描述

Two images A and B are given, represented as binary, square matrices of the same size. (A binary matrix has only 0s and 1s as values.)

We translate one image however we choose (sliding it left, right, up, or down any number of units), and place it on top of the other image. After, the overlap of this translation is the number of positions that have a 1 in both images.

(Note also that a translation does not include any kind of rotation.)

What is the largest possible overlap?

Example 1:

Input: A = [[1,1,0],
[0,1,0],
[0,1,0]]
B = [[0,0,0],
[0,1,1],
[0,0,1]]
Output: 3
Explanation: We slide A to right by 1 unit and down by 1 unit.

Notes:

  • 1 <= A.length = A[0].length = B.length = B[0].length <= 30
  • 0 <= A[i][j], B[i][j] <= 1

题目大意

两个形状相同的正方形矩阵,求用什么体位把它两个重叠在一起,然后重叠部分中1的个数最多。

解题方法

思路挺好玩的,直接找出所有1的位置,然后对两个矩阵的所有这些位置进行求差。然后统计这些差出现最多的次数是多少。

两个坐标的差是什么含义?就是把其中一个坐标移动到另一个坐标需要移动的向量。因此,在遍历过程中,我们找出了A中所有值为1的坐标移动到B中所有值为1的坐标需要移动的向量。那么,在这些向量中出现次数最多的向量就是我们要求的整个矩阵应该移动的向量。这个向量出现的次数,就是我们向该向量方向移动了之后,能重叠的1的个数。

结尾的or [0]挺有意思,防止了d.values()是空。

Python代码如下:

class Solution:
def largestOverlap(self, A, B):
"""
:type A: List[List[int]]
:type B: List[List[int]]
:rtype: int
"""
N = len(A)
LA = [(xi, yi) for xi in range(N) for yi in range(N) if A[xi][yi]]
LB = [(xi, yi) for xi in range(N) for yi in range(N) if B[xi][yi]]
d = collections.Counter([(x1 - x2, y1 - y2) for (x1, y1) in LA for (x2, y2) in LB])
return max(d.values() or [0])

二刷的时候使用C++,首先是上面同样的做法,没有优化的代码如下:

class Solution {
public:
int largestOverlap(vector<vector<int>>& A, vector<vector<int>>& B) {
map<pair<int, int>, int> move;
vector<pair<int, int>> A1s, B1s;
for (int i = 0; i < A.size(); ++i) {
for (int j = 0; j < A[0].size(); ++j) {
if (A[i][j])
A1s.push_back({i, j});
}
}
for (int i = 0; i < B.size(); ++i) {
for (int j = 0; j < B[0].size(); ++j) {
if (B[i][j])
B1s.push_back({i, j});
}
}
int res = 0;
for (auto a : A1s) {
for (auto b : B1s) {
pair<int, int> dir = make_pair(b.first - a.first, b.second - a.second);
move[dir]++;
res = max(res, move[dir]);
}
}
return res;
}
};

上面这个代码确实啰嗦了,看了寒神的答案,感觉自愧不如啊!

寒神的做法的优点:第一,注意到了题目给的A和B是大小相等的正方形!第二,遍历正方形的方式使用的是i[0,N*N)区间里,然后[i/N][i%N]这个求位置方法,可以把两重循环简写成一重(但是时间复杂没有变化)。第三,使用了数字表示向量,即把一个向量的行数*100+列数,比如第13行第19列,可以用一个数字表示1319。寒神告诉我们,这个100的选择是因为太小的话不能有效区分,应该最小是2N。

class Solution {
public:
int largestOverlap(vector<vector<int>>& A, vector<vector<int>>& B) {
const int N = A.size();
unordered_map<int, int> move;
vector<int> A1s, B1s;
for (int i = 0; i < N * N; ++i) {
if (A[i / N][i % N])
A1s.push_back((i / N) * 100 + i % N);
if (B[i / N][i % N])
B1s.push_back((i / N) * 100 + i % N);
}
int res = 0;
for (auto a : A1s) {
for (auto b : B1s) {
move[b - a]++;
res = max(res, move[b - a]);
}
}
return res;
}
};

参考资料:

https://blog.csdn.net/zjucor/article/details/80298134
https://leetcode.com/problems/image-overlap/discuss/150504/Python-Easy-Logic
https://leetcode.com/problems/image-overlap/discuss/130623/C%2B%2BJavaPython-Straight-Forward

日期

2018 年 9 月 10 日 —— 教师节快乐!
2018 年 12 月 28 日 —— 元旦假期到了

【LeetCode】835. Image Overlap 解题报告(Python & C++)的更多相关文章

  1. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  2. LeetCode 1 Two Sum 解题报告

    LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...

  3. 【LeetCode】Permutations II 解题报告

    [题目] Given a collection of numbers that might contain duplicates, return all possible unique permuta ...

  4. 【LeetCode】Island Perimeter 解题报告

    [LeetCode]Island Perimeter 解题报告 [LeetCode] https://leetcode.com/problems/island-perimeter/ Total Acc ...

  5. 【LeetCode】01 Matrix 解题报告

    [LeetCode]01 Matrix 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/01-matrix/#/descripti ...

  6. 【LeetCode】Largest Number 解题报告

    [LeetCode]Largest Number 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/largest-number/# ...

  7. 【LeetCode】Gas Station 解题报告

    [LeetCode]Gas Station 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/gas-station/#/descr ...

  8. LeetCode: Unique Paths II 解题报告

    Unique Paths II Total Accepted: 31019 Total Submissions: 110866My Submissions Question Solution  Fol ...

  9. Leetcode 115 Distinct Subsequences 解题报告

    Distinct Subsequences Total Accepted: 38466 Total Submissions: 143567My Submissions Question Solutio ...

随机推荐

  1. Python基础之基本运算符

    目录 1. 算数运算符 2. 比较运算符 3. 赋值运算符 4. 逻辑运算符 5. 身份运算 6. 运算符优先级 1. 算数运算符 常用算术运算符使用方法如下: x = 5 y = 2 a = x + ...

  2. lua table与json的之间的互相转换高性能c++实现

    请自行约束两种语言数据结构语法上的不同,避开如下问题: 1.json本身不约束key是否符合一个编程语言中的变量名,所以编写用于和编程语言数据结构交互的json代码时应该注意key是否正确. 2.lu ...

  3. Android editttext只能输入不能删除(选中后被软键盘遮住)

    感谢https://www.dutycode.com/post-20.html: 解决方法:在布局外外嵌一层scrollview.

  4. 淘宝、网易移动端 px 转换 rem 原理,Vue-cli 实现 px 转换 rem

       在过去的一段时间里面一直在使用Vue配合 lib-flexible和px2rem-loader配合做移动端的网页适配.秉着求知的思想,今天决定对他的原理进行分析.目前网上比较主流使用的就是淘宝方 ...

  5. CentOS 初体验三: Yum 安装、卸载软件

    一:Yum 简介 Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包管理,能够从指 ...

  6. docker之镜像制作

    #:下载镜像并初始化系统 root@ubuntu:~# docker pull centos #:创建目录 root@ubuntu:/opt# mkdir dockerfile/{web/{nginx ...

  7. window 查看端口占用情况

    查看哪个进程在用 netstat -aon|findstr "8080" TCP    0.0.0.0:8080           0.0.0.0:0              ...

  8. 【Java多线程】Java 中断

    如何安全的结束一个正在运行的线程 java.lang.Thread类包含了一些常用的方法,如:start(), stop(), stop(Throwable) ,suspend(), destroy( ...

  9. 4.Vue.js-起步

    Vue.js 起步 每个 Vue 应用都需要通过实例化 Vue 来实现. 语法格式如下: var vm = new Vue({ // 选项 }) 接下来让我们通过实例来看下 Vue 构造器中需要哪些内 ...

  10. SQL注入 (1) SQL注入类型介绍

    SQL注入 SQL注入介绍与分类 1. 什么是sql注入 通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. 2. sql注入类型 按照注入 ...