日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

程序员面试金典 - 面试题 17.24. 最大子矩阵(转成一维最大子序和 DP)

發(fā)布時(shí)間:2024/7/5 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 程序员面试金典 - 面试题 17.24. 最大子矩阵(转成一维最大子序和 DP) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1. 題目
    • 2. 解題
      • 2.1 前綴和(超時(shí))
      • 2.2 動(dòng)態(tài)規(guī)劃

1. 題目

給定一個(gè)正整數(shù)和負(fù)整數(shù)組成的 N × M 矩陣,編寫代碼找出元素總和最大的子矩陣

返回一個(gè)數(shù)組 [r1, c1, r2, c2],其中 r1, c1 分別代表子矩陣左上角的行號(hào)和列號(hào),r2, c2 分別代表右下角的行號(hào)和列號(hào)。
若有多個(gè)滿足條件的子矩陣,返回任意一個(gè)均可。

示例: 輸入: [[-1,0],[0,-1] ] 輸出: [0,1,0,1]說(shuō)明: 1 <= matrix.length, matrix[0].length <= 200

來(lái)源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/max-submatrix-lcci
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

2. 解題

類似題目: LeetCode 363. 矩形區(qū)域不超過(guò) K 的最大數(shù)值和(DP+set二分)

2.1 前綴和(超時(shí))

  • 求出每個(gè)位置與(0,0)構(gòu)成的子矩陣的和
  • 4層 for 循環(huán)遍歷左上角為(x,y),右下角為(i,j)的子矩陣
  • 其和為 sum=prefixsum[i][j]?prefixsum[x?1][j]?prefixsum[i][y?1]+prefixsum[x?1][y?1]sum = prefixsum[i][j]-prefixsum[x-1][j]-prefixsum[i][y-1]+prefixsum[x-1][y-1]sum=prefixsum[i][j]?prefixsum[x?1][j]?prefixsum[i][y?1]+prefixsum[x?1][y?1]
  • 復(fù)雜度 O(m2n2)O(m^2n^2)O(m2n2),通過(guò)14/25個(gè)測(cè)試
class Solution { public:vector<int> getMaxMatrix(vector<vector<int>>& matrix) {int m = matrix.size(), n = matrix[0].size(), i, j, x, y;int sum, maxSum = INT_MIN;vector<vector<int>> prefixsum(matrix);for(i = 0; i < m; ++i){for(j = 0; j < n; ++j){if(i > 0)prefixsum[i][j] += prefixsum[i-1][j];if(j > 0)prefixsum[i][j] += prefixsum[i][j-1];if(i>0 && j>0)prefixsum[i][j] -= prefixsum[i-1][j-1];// cout << prefixsum[i][j] << " ";}// cout << endl;}vector<int> ans(4);for(i = 0; i < m; i++){for(j = 0; j < n; ++j){for(x = 0; x <= i; x++){for(y = 0; y <= j; y++){sum = prefixsum[i][j];if(x > 0)sum -= prefixsum[x-1][j];if(y > 0)sum -= prefixsum[i][y-1];if(x > 0 && y > 0)sum += prefixsum[x-1][y-1];if(sum > maxSum){maxSum = sum;ans[0] = x, ans[1] = y;ans[2] = i, ans[3] = j;}}}}}return ans;} };

2.2 動(dòng)態(tài)規(guī)劃

類似題目:
LeetCode 152. 乘積最大子序列(DP)
本題參考:LeetCode 53. 最大子序和(動(dòng)態(tài)規(guī)劃),本質(zhì)一樣。

  • 2層for循環(huán)先把所有可能的行組合找出來(lái)
  • 然后列向求和,壓扁它
  • 對(duì)這個(gè)壓扁的一維數(shù)組求最大子序和即可
  • 時(shí)間復(fù)雜度 O(m2n)O(m^2n)O(m2n)
class Solution { public:vector<int> getMaxMatrix(vector<vector<int>>& matrix) {int m = matrix.size(), n = matrix[0].size(), i, j, k, l, r;int sum, maxSum = INT_MIN;vector<int> sumRi_Rj(n);//【i,j】行的列向和vector<int> ans(4);for(i = 0; i < m; ++i){sumRi_Rj.clear();sumRi_Rj.resize(n,0);for(j = i; j < m; ++j){for(k = 0; k < n; ++k){sumRi_Rj[k] += matrix[j][k];//列向和}//一維dp,初始化sum = sumRi_Rj[0];l = r = 0;if(sum > maxSum){maxSum = sum;ans[0] = i, ans[1] = l;ans[2] = j, ans[3] = r;}for(k = 1; k < n; ++k){ //轉(zhuǎn)為一維數(shù)組sumRi_Rj最大子數(shù)組和if(sum > 0){sum += sumRi_Rj[k];r = k;}else{sum = sumRi_Rj[k];l = r = k;}if(sum > maxSum){maxSum = sum;ans[0] = i, ans[1] = l;ans[2] = j, ans[3] = r;}}}}return ans;} };

384 ms 12.7 MB

總結(jié)

以上是生活随笔為你收集整理的程序员面试金典 - 面试题 17.24. 最大子矩阵(转成一维最大子序和 DP)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。