《Cracking the Coding Interview》——第18章:难题——题目12

2014-04-29 04:36

题目:最大子数组和的二位扩展:最大子矩阵和。

解法:一个维度上进行枚举,复杂度O(n^2);另一个维度执行最大子数组和算法,复杂度O(n)。总体时间复杂度为O(n^3),还需要O(n)额外空间。

代码:


 1 // 18.12 Given an n x n matrix, find the submatrix with largest sum. Return the sum as the result.
2 #include <algorithm>
3 #include <climits>
4 #include <iostream>
5 #include <vector>
6 using namespace std;
7
8 class Solution {
9 public:
10 int largestSubmatrixSum (const vector<vector<int> > &matrix) {
11 n = matrix.size();
12 if (n == 0) {
13 return 0;
14 }
15 m = matrix[0].size();
16 if (m == 0) {
17 return 0;
18 }
19
20 int i, j, k;
21 vector<int> v;
22 int msum;
23 int sum;
24
25 v.resize(m);
26 msum = INT_MIN;
27 for (i = 0; i < n; ++i) {
28 fill(v.begin(), v.end(), 0);
29 for (j = i; j < n; ++j) {
30 for (k = 0; k < m; ++k) {
31 v[k] += matrix[j][k];
32 }
33 sum = maxSubarraySum(v, m);
34 msum = max(msum, sum);
35 }
36 }
37 v.clear();
38 return msum;
39 };
40 private:
41 int n, m;
42
43 int maxSubarraySum(const vector<int> &v, int n) {
44 int msum;
45 int sum;
46 int i;
47
48 msum = INT_MIN;
49 for (i = 0; i < n; ++i) {
50 if (v[i] >= 0) {
51 msum = max(msum, v[i]);
52 break;
53 }
54 }
55 if (i == n) {
56 return msum;
57 }
58
59 msum = sum = 0;
60 for (i = 0; i < n; ++i) {
61 sum += v[i];
62 msum = max(msum, sum);
63 sum = max(sum, 0);
64 }
65
66 return msum;
67 };
68 };
69
70 int main()
71 {
72 int i, j;
73 int n, m;
74 vector<vector<int> > matrix;
75 Solution sol;
76
77 while (cin >> n >> m && (n > 0 && m > 0)) {
78 matrix.resize(n);
79 for (i = 0; i < n; ++i) {
80 matrix[i].resize(m);
81 for (j = 0; j < m; ++j) {
82 cin >> matrix[i][j];
83 }
84 }
85 cout << sol.largestSubmatrixSum(matrix) << endl;
86
87 for (i = 0; i < n; ++i) {
88 matrix[i].clear();
89 }
90 matrix.clear();
91 }
92
93 return 0;
94 }

《Cracking the Coding Interview》——第18章:难题——题目12,布布扣,bubuko.com

时间: 2024-10-26 00:42:39

《Cracking the Coding Interview》——第18章:难题——题目12的相关文章

《Cracking the Coding Interview》——第18章:难题——题目10

2014-04-29 04:22 题目:给定一堆长度都相等的单词,和起点.终点两个单词,请从这堆单词中寻找一条变换路径,把起点词变成终点词,要求每次变换只能改一个字母. 解法:Leetcode中有Word Ladder,这题基本思路一致. 代码: 1 // 18.10 Given a list of words, all of same length. Given a source and a destionation words, you have to check if there exis

《Cracking the Coding Interview》——第18章:难题——题目9

2014-04-29 04:18 题目:有一连串的数被读入,设计一个数据结构,能随时返回当前所有数的中位数. 解法:用一个大顶堆,一个小顶堆将数分成数量最接近的两份,就能轻松得到中位数了. 代码: 1 // 18.9 A stream of integers are passed to you, you have to tell me the median as they keep coming in. 2 #include <climits> 3 #include <iostream&

《Cracking the Coding Interview》——第18章:难题——题目13

2014-04-29 04:40 题目:给定一个字母组成的矩阵,和一个包含一堆单词的词典.请从矩阵中找出一个最大的子矩阵,使得从左到右每一行,从上到下每一列组成的单词都包含在词典中. 解法:O(n^3)级别的时间和空间进行动态规划.这道题目和第17章的最后一题很像,由于这题的时间复杂度实在是高,我动手写了字典树进行加速.如果单纯用哈希表来作为词典,查询效率实际会达到O(n)级别,导致最终的算法复杂度为O(n^4).用字典树则可以加速到O(n^3),因为对于一个字符串"abcd",只需要

《Cracking the Coding Interview》——第18章:难题——题目11

2014-04-29 04:30 题目:给定一个由'0'或者'1'构成的二维数组,找出一个四条边全部由'1'构成的正方形(矩形中间可以有'0'),使得矩形面积最大. 解法:用动态规划思想,记录二维数组每个元素向上下左右四个方向各有多少个连续的'1',然后用O(n^3)时间计算出满足条件的最大正方形.时间复杂度O(n^3),空间复杂度O(n^2). 代码: 1 // 18.11 Given an NxN matrix of 0s and 1s, find out a subsquare whose

《Cracking the Coding Interview》——第18章:难题——题目6

2014-04-29 02:27 题目:找出10亿个数中最小的100万个数,假设内存可以装得下. 解法1:内存可以装得下?可以用快速选择算法得到无序的结果.时间复杂度总体是O(n)级别,但是常系数不小. 代码: 1 // 18.6 Find the smallest one million number among one billion numbers. 2 // Suppose one billion numbers can fit in memory. 3 // I'll use quic

《Cracking the Coding Interview》——第18章:难题——题目7

2014-04-29 03:05 题目:给定一个词典,其中某些词可能能够通过词典里其他的词拼接而成.找出这样的组合词里最长的一个. 解法:Leetcode上有Word Break这道题,和这题基本思路一致. 代码: 1 // 18.7 Given a list of words, find out the longest word made of other words in the list. 2 #include <iostream> 3 #include <string> 4

《Cracking the Coding Interview》——第18章:难题——题目2

2014-04-29 00:59 题目:设计一个洗牌算法,效率尽量快点,必须等概率. 解法:每次随机抽一张牌出来,最后都抽完了,也就洗好了.时间复杂度O(n^2),请看代码. 代码: 1 // 18.2 shuffle a deck of 52 cards, it must be perfect random. 2 #include <cstdio> 3 #include <cstdlib> 4 #include <ctime> 5 #include <vecto

《Cracking the Coding Interview》——第18章:难题——题目3

2014-04-29 01:02 题目:从m个整数里随机选出n个整数,要求等概率. 解法:和洗牌的算法类似,每次随机抽出一个数,抽n次即可.时间复杂度O(m * n),空间复杂度O(m). 代码: 1 // 18.3 pick m integers randomly from an array of n integer. 2 #include <cstdio> 3 #include <cstdlib> 4 #include <ctime> 5 #include <

《Cracking the Coding Interview》——第18章:难题——题目5

2014-04-29 01:51 题目:你有一个文本文件,每行一个单词.给定两个单词,请找出这两个单词在文件中出现的其中一对位置,使得这两个位置的距离最短. 解法:我的思路是建立倒排索引,计算出所有单词出现的所有位置.下面代码只给出了两个索引的处理方法.倒排索引一般以链表的形式出现,通过顺序扫描两个链表,类似归并排序算法中的merge过程,就能够找出最短距离.请看代码. 代码: 1 // 18.5 Given a text file containing words, find the shor