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 kMaximum 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 All in One 题目汇总

[CareerCup] 18.12 Largest Sum Submatrix 和最大的子矩阵的更多相关文章

  1. Google - Largest Sum Submatrix

    Given an NxN matrix of positive and negative integers, write code to find the submatrix with the lar ...

  2. [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 ...

  3. [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 ...

  4. [LeetCode] Split Array Largest Sum 分割数组的最大值

    Given an array which consists of non-negative integers and an integer m, you can split the array int ...

  5. Split Array Largest Sum

    Given an array which consists of non-negative integers and an integer m, you can split the array int ...

  6. Leetcode: Split Array Largest Sum

    Given an array which consists of non-negative integers and an integer m, you can split the array int ...

  7. 410. Split Array Largest Sum

    做了Zenefits的OA,比面经里的简单多了..害我担心好久 阴险的Baidu啊,完全没想到用二分,一开始感觉要用DP,类似于极小极大值的做法. 然后看了答案也写了他妈好久. 思路是再不看M的情况下 ...

  8. [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 ...

  9. 动态规划——Split Array Largest Sum

    题意大概就是,给定一个包含非负整数的序列nums以及一个整数m,要求把序列nums分成m份,并且要让这m个子序列各自的和的最大值最小(minimize the largest sum among th ...

随机推荐

  1. APUE包含头文件"apue.h"问题

    下载源码 从unix高级编程书籍官网下载书籍的上的所有源码. wget http://www.apuebook.com/src.tar.gz 解压这个文件 tar -zxvf src.tar.gz 解 ...

  2. 11g新特性-如何禁用自动统计信息收集作业

    一.11g中auto stats gather job被集成到了auto task中. SQL> select client_name,status from DBA_AUTOTASK_CLIE ...

  3. c语言的字符串操作(比较详细)

    1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1) 附加字符串 strncat(p, p1, n) 附加指定长度 ...

  4. Codeforces VK Cup 2012 Round 3 A. Variable, or There and Back Again(dfs)

    题目链接:http://codeforces.com/problemset/problem/164/A 思路:用vector分别保留原图和发图,然后分别从val值为1的点正向遍历,va值为2的点反向遍 ...

  5. 即时通讯(IM-instant messager)

    即时通讯又叫实时通讯,简单来说就是两个及以上的人使用网络进行文字.文件.语音和视频的交流. 首先,进行网络进行通信,肯定需要网络协议,即时通讯专用的协议就是xmpp.xmpp协议要传递的消息类型是xm ...

  6. WebAPI接口调用身份验证

    Common public interface ICacheWriter { void AddCache(string key, object value, DateTime expDate); vo ...

  7. 用padding与margin做多个元素的等间距分布

    这样做的好处是不管有多少个元素等间距分布,都可以直接写在li中,而且由于是给a设定的样式,所以在字数不一致的情况下,样式仍然是统一的. html: <!DOCTYPE html> < ...

  8. POJ 3080 后缀数组/KMP

    题目链接:http://poj.org/problem?id=3080 题意:给定n个DNA串,求最长公共子串.如果最长公共子串的长度小于3时输出no significant commonalitie ...

  9. XAML数据绑定(Data Binding)

    XAML数据绑定(Data Binding)   Data Binding可以使得XAML标签属性的赋值更为灵活和方便.在绑定过程中,获取数据的标签成为目标标签:提供数据的标签成为源标签.在XAML中 ...

  10. JS_ECMA基本语法中的几种封装的小函数

      先来回顾一下我们的字符串: 字符串方法: str.length str.charAt(i):取字符串中的某一个; str.indexOf('e');找第一个出现的位置;找不到返回-1; str.l ...