二維數組子數組最大和、二維矩陣子矩陣最大和

  共兩道題,都是不難,還是記錄一下:
1、在一個一維數組中,找出連續子數組的最大和:LeetCode - 53. Maximum Subarray
2、在一個二維矩陣中,找出子矩陣最大和:https://www.51nod.com/Challenge/Problem.html#problemId=1051

一、數組子數組最大和

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

  就是連續的子數組中,找出和最大的。首先最容易想到的就是 O(N)O(N) 的 solution,用一個 cur 值記錄之前總和,當總和加當前值 < 當前位置值時,cur 就變成當前位置值,否則就累加。

int maxSubArray(vector<int>& nums) {
    int max_sum = INT_MIN, cur_sum = 0;
    for (const int& i : nums) {
        cur_sum = max(i, cur_sum + i);
        max_sum = max(max_sum, cur_sum);
    }
    return max_sum;
}

二、二維矩陣子矩陣最大和

一個 M*N 的矩陣,找到此矩陣的一個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。
例如:3*3 的矩陣:
-1 3 -1
2 -1 3
-3 1 2
和最大的子矩陣是(和爲 7):
3 -1
-1 3
1 2

  其實,和上邊的題一樣的,不過就是多了一(維,上邊的題,其實是用一個 dp 數組,存儲以每個位置結尾的子數組最大和,這道題就是用一個 pre_sum 數組,存儲每一列爲結尾的子矩陣最大和
  原題輸入是先是列,然後是行,坑死。。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int maxSum(vector<vector<int>> &arr) {
	if (arr.empty()) return 0;
	const int M = arr.size(), N = arr[0].size();
	int max_sum = INT_MIN;
	for (int i = 0; i < M; i++) {
		vector<int> pre_sum(N, 0);	// 每一列的presum
		for (int j = i; j < M; j++) { // [i, j]行
			int cur = 0;
			for (int k = 0; k < N; k++) {
				pre_sum[k] += arr[j][k];
				cur += pre_sum[k];
				max_sum = max(max_sum, cur);
				cur = cur < 0 ? 0 : cur;
			}
			//for (const int& p : pre_sum)
			//	cout << p << " ";
			//cout << endl;
		}
	}
	return max_sum;
}

int main() {
	int m, n;
	cin >> n >> m;
	vector<vector<int>> mat(m, vector<int>(n));
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> mat[i][j];
	cout << maxSum(mat) << endl;
}

pre_sum 結果
-1 3 -1
1 2 2
-2 3 4
2 -1 3
-1 0 5
-3 1 2

  看懂 pre_sum 的輸出,就看懂了,其實 pre_sum 的計算有很多重複的部分,不過AC了就記錄個思想就好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章