[CareerCup] 18.12 Largest Sum Submatrix 和最大的子矩阵
18.12 Given an NxN matrix of positive and negative integers, write code to find the submatrix with the largest possible sum.
这道求和最大的子矩阵,跟LeetCode上的Maximum Size Subarray Sum Equals k和Maximum Subarray很类似。这道题不建议使用brute force的方法,因为实在是不高效,我们需要借鉴上面LeetCode中的建立累计和矩阵的思路,我们先来看这道题的第一种解法,由于建立好累计和矩阵,那么我们通过给定了矩阵的左上和右下两个顶点的坐标可以在O(1)的时间内快速的求出矩阵和,所以我们要做的就是遍历矩阵中所有的子矩阵,然后比较其矩阵和,返回最大的即可,时间复杂度为O(n4)。
解法一:
vector<vector<int>> precompute(vector<vector<int>> &matrix) {
vector<vector<int>> sumMatrix = matrix;
for (int i = ; i < matrix.size(); ++i) {
for (int j = ; j < matrix[i].size(); ++j) {
if (i == && j == ) {
sumMatrix[i][j] = matrix[i][j];
} else if (j == ) {
sumMatrix[i][j] = sumMatrix[i - ][j] + matrix[i][j];
} else if (i == ) {
sumMatrix[i][j] = sumMatrix[i][j - ] + matrix[i][j];
} else {
sumMatrix[i][j] = sumMatrix[i - ][j] + sumMatrix[i][j - ] - sumMatrix[i - ][j - ] + matrix[i][j];
}
}
}
return sumMatrix;
}
int compute_sum(vector<vector<int>> &sumMatrix, int i1, int i2, int j1, int j2) {
if (i1 == && j1 == ) {
return sumMatrix[i2][j2];
} else if (i1 == ) {
return sumMatrix[i2][j2] - sumMatrix[i2][j1 - ];
} else if (j1 == ) {
return sumMatrix[i2][j2] - sumMatrix[i1 - ][j2];
} else {
return sumMatrix[i2][j2] - sumMatrix[i2][j1 - ] - sumMatrix[i1 - ][j2] + sumMatrix[i1 - ][j1 - ];
}
}
int get_max_matrix(vector<vector<int>> &matrix) {
int res = INT_MIN;
vector<vector<int>> sumMatrix = precompute(matrix);
for (int r1 = ; r1 < matrix.size(); ++r1) {
for (int r2 = r1; r2 < matrix.size(); ++r2) {
for (int c1 = ; c1 < matrix[].size(); ++c1) {
for (int c2 = c1; c2 < matrix[].size(); ++c2) {
int sum = compute_sum(sumMatrix, r1, r2, c1, c2);
res = max(res, sum);
}
}
}
}
return res;
}
其实这道题的解法还能进一步优化到O(n3),根据LeetCode中的那道Maximum Subarray的解法,我们可以对一维数组求最大子数组的时间复杂度优化到O(n),那么我们可以借鉴其的思路,由于二维数组中遍历所有的列数相等的子矩阵的时间为O(n2),每一行的遍历是O(n),所以整个下来的时间复杂度即为O(n3),参见代码如下:
解法二:
int max_subarray(vector<int> &array) {
int res = , sum = ;
for (int i = ; i < array.size(); ++i) {
sum += array[i];
res = max(res, sum);
sum = max(sum, );
}
return res;
}
int max_submatrix(vector<vector<int>> &matrix) {
if (matrix.empty() || matrix[].empty()) return ;
int res = ;
for (int r1 = ; r1 < matrix.size(); ++r1) {
vector<int> sum(matrix[].size());
for (int r2 = r1; r2 < matrix.size(); ++r2) {
for (int c = ; c < matrix[].size(); ++c) {
sum[c] += matrix[r2][c];
}
int t = max_subarray(sum);
res = max(res, t);
}
}
return res;
}
[CareerCup] 18.12 Largest Sum Submatrix 和最大的子矩阵的更多相关文章
- Google - Largest Sum Submatrix
Given an NxN matrix of positive and negative integers, write code to find the submatrix with the lar ...
- [CareerCup] 18.13 Largest Rectangle of Letters
18.13 Given a list of millions of words, design an algorithm to create the largest possible rectangl ...
- [CareerCup] 17.8 Contiguous Sequence with Largest Sum 连续子序列之和最大
17.8 You are given an array of integers (both positive and negative). Find the contiguous sequence w ...
- [LeetCode] Split Array Largest Sum 分割数组的最大值
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- Split Array Largest Sum
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- Leetcode: Split Array Largest Sum
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- 410. Split Array Largest Sum
做了Zenefits的OA,比面经里的简单多了..害我担心好久 阴险的Baidu啊,完全没想到用二分,一开始感觉要用DP,类似于极小极大值的做法. 然后看了答案也写了他妈好久. 思路是再不看M的情况下 ...
- [Swift]LeetCode410. 分割数组的最大值 | Split Array Largest Sum
Given an array which consists of non-negative integers and an integer m, you can split the array int ...
- 动态规划——Split Array Largest Sum
题意大概就是,给定一个包含非负整数的序列nums以及一个整数m,要求把序列nums分成m份,并且要让这m个子序列各自的和的最大值最小(minimize the largest sum among th ...
随机推荐
- V for Vendetta
V for Vendetta V字仇杀队 复仇者V 安迪·沃卓斯基 and Larry Wachowski 思想,是最强大的武器.因为,世界上的独裁政府,有一个共同特点就是推行洗脑和愚民政策. 经典台 ...
- HDU 2896 病毒侵袭(AC自动机)
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 智能车学习(十五)——K60野火2013版例程
一.中断函数注册方法: 1.格式: 配置某个功能的中断 注册中断函数 开启中断 2.一个例子 pit_init_ms(PIT0,);//定时中断初始化 set_vector_handler(PIT0_ ...
- ArrayList集合&特殊集合
一.ArrayList集合 集合内可以放不同类型的元素 另:object类型为所有数据类型的基类 添加元素:.add(); 清空集合:al.clear(); 克隆集合:.clone(); 判断是否包含 ...
- EL表达式详解及应用实例
1. EL是JSP内置的表达式语言! * jsp2.0开始,不让再使用java脚本,而是使用el表达式和动态标签来替代java脚本! * EL替代的是<%= ... %>,也就是说,EL只 ...
- css新增选择器
- 数据库分库分表sharding1
sharding Vertical Sharding 把数据分散到多台物理机(我们称之为Shard) 实现Sharding需要解决一系列关键的技术问题,这些问题主要包括:切分策略.节点路由.全局主键生 ...
- John the Ripper
John the RipperJohn the Ripper(简称John)是一款著名的密码破解工具.它主要针对各种Hash加密的密文.它不同于Rainbow Table方式.它采用实时运算的方式和密 ...
- sprint3冲刺第一天
1.计划了sprint3要做的内容: 整合前台和后台,然后发布让用户使用,然后给我们反馈再进行改进 2.backlog表格: ID 任务 Est 做了什么 1 实现用户登录与权限判定 4 进行用户分类 ...
- HTML5拖放事件(Drag-and-Drop,DnD)
拖放 拖放是一种常见的特性,即抓取对象以后拖到另一个位置.在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. 拖放是在“拖放源(drag source)”和“拖放目标(drop target ...