c++ 解決區間最大數和矩陣最大面積

給定一個實數序列,設計一個最有效的算法,找到一個總和數最大的區間等于某個事先給定的數字。

我們可以使用前綴和和哈希表來設計一個高效的算法。這個算法的時間復雜度是 O(n),空間復雜度也是 O(n)。

#include <vector>
#include <unordered_map>
#include <iostream>std::pair<int, int> findMaxLengthSubarrayWithSum(const std::vector<double>& arr, double targetSum) {std::unordered_map<double, int> sumIndex; // 用于存儲前綴和及其索引double currentSum = 0; // 當前的前綴和int maxLength = 0; // 最長子數組的長度int endIndex = -1; // 最長子數組的結束索引sumIndex[0] = -1; // 初始化前綴和為0的索引為-1for (int i = 0; i < arr.size(); ++i) {currentSum += arr[i]; // 計算當前前綴和double complement = currentSum - targetSum; // 計算需要尋找的互補和if (sumIndex.find(complement) != sumIndex.end()) { // 如果找到了互補和int length = i - sumIndex[complement]; // 計算子數組長度if (length > maxLength) { // 如果這個子數組更長maxLength = length; // 更新最大長度endIndex = i; // 更新結束索引}}if (sumIndex.find(currentSum) == sumIndex.end()) { // 如果這個前綴和之前沒出現過sumIndex[currentSum] = i; // 記錄這個前綴和的索引}}if (endIndex != -1) { // 如果找到了符合條件的子數組return {endIndex - maxLength + 1, endIndex}; // 返回起始和結束索引} else {return {-1, -1}; // 如果沒找到,返回{-1, -1}}
}int main() {std::vector<double> arr = {1.0, 4.0, 20.0, 3.0, 10.0, 5.0}; // 示例數組double targetSum = 33.0; // 目標和auto result = findMaxLengthSubarrayWithSum(arr, targetSum); // 調用函數查找子數組if (result.first != -1) { // 如果找到了符合條件的子數組std::cout << "找到了和為 " << targetSum << " 的最長子數組,索引范圍: [" << result.first << ", " << result.second << "]" << std::endl;} else { // 如果沒有找到符合條件的子數組std::cout << "沒有找到和為 " << targetSum << " 的子數組" << std::endl;}return 0;
}

這個算法的工作原理如下:

  1. 我們使用一個哈希表 sumIndex 來存儲每個前綴和及其對應的索引。
  2. 我們遍歷數組,不斷累加當前的和 currentSum
  3. 對于每個位置,我們計算 complement = currentSum - targetSum。如果這個 complement 存在于我們的哈希表中,那么說明我們找到了一個和為 targetSum 的子數組。
  4. 我們記錄找到的最長的子數組。
  5. 如果當前的 currentSum 還沒有在哈希表中,我們就將它加入哈希表。

這個算法的優點是:

  • 時間復雜度為 O(n),因為我們只需要遍歷一次數組。
  • 空間復雜度為 O(n),用于存儲哈希表。
  • 它可以處理包含正數、負數和零的數組。
  • 它可以找到最長的符合條件的子數組。

這個算法比簡單的滑動窗口方法更有效,因為它可以處理包含負數的情況,并且可以在一次遍歷中找到最長的符合條件的子數組。

第二個問題,在一個二維矩陣中,尋找一個矩陣的區域,使其中的數字之和達到最大值,著名的"最大子矩陣和"問題。我們可以使用Kadane算法的二維擴展來解決這個問題。以下是C++實現,并附有中文注釋:

#include <vector>
#include <climits>
#include <iostream>struct SubMatrix {int top, left, bottom, right, sum;
};SubMatrix findMaxSumSubMatrix(const std::vector<std::vector<int>>& matrix) {int rows = matrix.size();if (rows == 0) return {0, 0, 0, 0, 0};int cols = matrix[0].size();if (cols == 0) return {0, 0, 0, 0, 0};SubMatrix result = {0, 0, 0, 0, INT_MIN}; // 存儲最終結果std::vector<int> temp(rows, 0); // 臨時數組,用于存儲列的和// 枚舉所有可能的左右列邊界for (int left = 0; left < cols; ++left) {std::fill(temp.begin(), temp.end(), 0); // 重置臨時數組for (int right = left; right < cols; ++right) {// 將當前列加到臨時數組中for (int i = 0; i < rows; ++i) {temp[i] += matrix[i][right];}// 在臨時數組上應用一維Kadane算法int currentSum = 0;int maxSum = INT_MIN;int tempTop = 0, top = 0, bottom = 0;for (int i = 0; i < rows; ++i) {currentSum += temp[i];if (currentSum > maxSum) {maxSum = currentSum;top = tempTop;bottom = i;}if (currentSum < 0) {currentSum = 0;tempTop = i + 1;}}// 更新全局最大值if (maxSum > result.sum) {result = {top, left, bottom, right, maxSum};}}}return result;
}int main() {std::vector<std::vector<int>> matrix = {{1, 2, -1, -4, -20},{-8, -3, 4, 2, 1},{3, 8, 10, 1, 3},{-4, -1, 1, 7, -6}};SubMatrix result = findMaxSumSubMatrix(matrix);std::cout << "最大子矩陣和為: " << result.sum << std::endl;std::cout << "子矩陣位置: (" << result.top << "," << result.left << ") 到 ("<< result.bottom << "," << result.right << ")" << std::endl;return 0;
}

這個算法的工作原理如下:

  1. 我們枚舉矩陣的所有可能的左右列邊界。
  2. 對于每一對左右邊界,我們計算這些列之間所有元素的和,存儲在一個臨時數組中。
  3. 在這個臨時數組上,我們應用一維的Kadane算法來找到最大子數組和,這個子數組對應于我們要找的子矩陣的上下邊界。
  4. 我們跟蹤全局最大和及其對應的子矩陣位置。
  5. 最后返回具有最大和的子矩陣。

這個算法的時間復雜度是O(n^3),其中n是矩陣的邊長(假設矩陣是方陣)。雖然這不是最優的解法,但它是較為直觀且易于實現的方法。

對于更大的矩陣,存在更高效的算法,如使用二維線段樹或者二維樹狀數組的方法,它們可以將時間復雜度降低到O(n^2 log n)或O(n^2)。但這些方法的實現會更加復雜。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/37395.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/37395.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/37395.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python查找支撐數 青少年編程電子學會python編程等級考試三級真題解析2022年3月

目錄 python查找支撐數 一、題目要求 1、編程實現 2、輸入輸出 二、算法分析 三、程序代碼 四、程序說明 五、運行結果 六、考點分析 七、 推薦資料 1、藍橋杯比賽 2、考級資料 3、其它資料 python查找支撐數 2022年3月 python編程等級考試級編程題 一、題目要求…

RabbitMQ 的經典問題

文章目錄 前言一、防止消息丟失1.1 ConfirmCallback/ReturnCallback1.2 持久化1.3 消費者確認消息 二、防止重復消費三、處理消息堆積四、有序消費消息五、實現延時隊列六、小結推薦閱讀 前言 當設計和運維消息隊列系統時&#xff0c;如 RabbitMQ&#xff0c;有幾個關鍵問題需…

第100+13步 ChatGPT學習:R實現決策樹分類

基于R 4.2.2版本演示 一、寫在前面 有不少大佬問做機器學習分類能不能用R語言&#xff0c;不想學Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi轉一下就得了唄。 加上最近也沒啥內容寫了&#xff0c;就幫各位搬運一下吧。 二、R代碼實現決策樹分類 &#xff08;…

【漏洞復現】宏景HCM人力資源信息管理系統——任意文件讀取漏洞

聲明&#xff1a;本文檔或演示材料僅供教育和教學目的使用&#xff0c;任何個人或組織使用本文檔中的信息進行非法活動&#xff0c;均與本文檔的作者或發布者無關。 文章目錄 漏洞描述漏洞復現測試工具 漏洞描述 宏景HCM人力資源信息管理系統是一款全面覆蓋人力資源管理各模塊…

docker pull 鏡像的時候遇到Pulling fs layer問題

最近遇到一個很奇怪的問題,docker pull 鏡像的時候,總是出現Pulling fs layer問題,導致鏡像拉取不成功,以前是安裝好docker,正常拉取鏡像都是沒什么問題的,在這里記錄一下這個問題的解決方法,當然,可能并不通用。 1、進入阿里云容器服務 地址:https://cr.console.aliy…

Spring Boot中的熱部署配置

Spring Boot中的熱部署配置 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將探討如何在Spring Boot項目中實現熱部署配置&#xff0c;提升開發效率和項…

C++實現Qt的信號+槽功能

在 Visual Studio (VS) 上使用 C 實現類似 Qt 的信號和槽機制是完全可能的&#xff0c;但 Qt 的信號和槽系統是基于其特定的元對象系統&#xff08;Meta-Object System, MOC&#xff09;的&#xff0c;這需要一些特定的預處理器和代碼生成步驟。 如果你不想使用 Qt&#xff0c;…

vue路由傳參和react 路由傳參

路由跳轉的方式 1、聲明式導航 <router-link to"導航的地址"> 2、編程式導航 編程式導航有三種方法來進行導航 router.push router.replace router.go params傳參和query傳參 1、 params 傳參(不在URL中顯示參數) 在父路由跳轉到子路由時&#xff0c;也可…

【Django】網上蛋糕項目商城-熱銷和新品

概念 本文將完成實現項目的熱銷和新品兩個分類的商品列表進行分頁展示。 熱銷和新品功能實現步驟 在head.html頭部頁面中點擊這兩個超鏈接向服務器發送請求。 在urls.py文件中定義該請求地址 path(goodsrecommend_list/,views.goodsrecommend_list) 在views.py文件中定義g…

JDBC中的批處理是什么?如何使用?

JDBC中的批處理是指將多個關聯的SQL語句組合成一個批處理&#xff0c;并將它們作為一個調用提交給數據庫。這種方法可以減少通信的資源消耗&#xff0c;從而提高性能。以下是關于JDBC批處理的具體使用和步驟&#xff1a; 1. JDBC批處理的基本概念 批處理定義&#xff1a;將多…

英飛凌TC3xx之一起認識GTM(十五)GTM常見配置問題總結

英飛凌TC3xx之一起認識GTM(十五)GTM常見配置問題總結 1 關于TGC/AGC的配置注意事項2 關于HOST_TRIG的使用3 關于SOMC模式中MCS與ARU的合并使用配置4 深入理解SOMP模式中RST_CCU0的配置5 關于CCUx中斷的使用6 TIM如何捕獲ATOM的輸出7 總結前面幾篇關鍵文章信息鏈接匯總如下: …

AV Foundation學習筆記二 - 播放器

ASSets AVFoundation框架的最核心的類是AVAsset&#xff0c;該類是整個AVFoundation框架設計的中心。AVAsset是一個抽象的&#xff08;意味著你不能調用AVAsset的alloc或者new方法來創建一個AVAsset實例對象&#xff0c;而是通過該類的靜態方法來創建實例對象&#xff09;、不…

DevOps CMDB平臺整合Jira工單

背景 在DevOps CMDB平臺建設的過程中&#xff0c;我們可以很容易的將業務應用所涉及的云資源&#xff08;WAF、K8S、虛擬機等&#xff09;、CICD工具鏈&#xff08;Jenkins、ArgoCD&#xff09;、監控、日志等一次性的維護到CMDB平臺&#xff0c;但隨著時間的推移&#xff0c;…

Stirling PDF 部署 - 強大的PDF Web在線編輯工具箱

簡介 這是一個強大的、可本地托管的、基于 Web 的 PDF 操作工具&#xff0c;可使用 Docker部署。它使您能夠對 PDF 文件執行各種操作&#xff0c;包括拆分、合并、轉換、重組、添加圖像、旋轉、壓縮等。這個本地托管的 Web 應用程序已經發展到包含一套全面的功能&#xff0c;可…

PHP爬蟲類的并發與多線程處理技巧

PHP爬蟲類的并發與多線程處理技巧 引言&#xff1a; 隨著互聯網的快速發展&#xff0c;大量的數據信息存儲在各種網站上&#xff0c;獲取這些數據已經成為很多業務場景下的需求。而爬蟲作為一種自動化獲取網絡信息的工具&#xff0c;被廣泛應用于數據采集、搜索引擎、輿情分析…

關于組織赴俄羅斯(莫斯科)第 28 屆國際汽車零部件、汽車維修設備和商品展覽會商務考察的通知

關于組織赴俄羅斯&#xff08;莫斯科&#xff09; 第 28 屆國際汽車零部件、汽車維修設備和商品展覽會商務考察的通知 展會名稱&#xff1a;俄羅斯&#xff08;莫斯科&#xff09;第 28 屆國際汽車零部件、汽車零部件、汽車維修設備和商品展覽會 時間&#xff1a;2024 年 8 月…

Python | Leetcode Python題解之第204題計數質數

題目&#xff1a; 題解&#xff1a; MX5000000 is_prime [1] * MX is_prime[0]is_prime[1]0 for i in range(2, MX):if is_prime[i]:for j in range(i * i, MX, i):#循環每次增加iis_prime[j] 0 class Solution:def countPrimes(self, n: int) -> int:return sum(is_prim…

【MongoDB】分布式數據庫入門級學習

SueWakeup 個人主頁&#xff1a;SueWakeup 系列專欄&#xff1a;為祖國的科技進步添磚Java 個性簽名&#xff1a;保留赤子之心也許是種幸運吧 本文封面由 凱楠&#x1f4f8;友情提供 凱楠&#x1f4f8; - 不夜長安 目錄 MongoDB 相關 數據庫排行榜單 MongoDB 中文官網 菜鳥…

如何把mkv轉成mp4?介紹一下將mkv轉成MP4的幾種方法

如何把mkv轉成mp4&#xff1f;如果你有一個MKV格式的視頻文件&#xff0c;但是需要將其轉換為MP4格式以便更廣泛地在各種設備和平臺上播放和共享&#xff0c;你可以通過進行簡單的文件格式轉換來實現。轉換MKV到MP4格式可以提供更好的兼容性&#xff0c;并確保你的視頻文件能夠…

在預訓練語言模型主流架構

文章目錄 編碼器-解碼器架構因果解碼器架構前綴解碼器架構在預訓練語言模型時代,自然語言處理領域廣泛采用了預訓練 + 微調的范式,并誕生了以 BERT 為代表的編碼器(Encoder-only)架構、以 GPT 為代表的解碼器(Decoder-only)架構和以 T5 為代表的編碼器-解碼器(Encoder-d…