class070 子數組最大累加和問題與擴展-上【算法】

class070 子數組最大累加和問題與擴展-上【算法】

在這里插入圖片描述

code1 53. 最大子數組和

// 累加和最大子數組和
// 給你一個整數數組 nums
// 請你找出一個具有最大累加和的非空子數組
// 返回其最大累加和
// 測試鏈接 : https://leetcode.cn/problems/maximum-subarray/

dp[i]:以i結尾的子數組[…i]的最大累加和
(1) nums[i] (2) dp[i-1]+nums[i] 二者取最大的
返回Max(dp[…])

code1 動態規劃
code2 空間壓縮

package class070;// 子數組最大累加和
// 給你一個整數數組 nums
// 返回非空子數組的最大累加和
// 測試鏈接 : https://leetcode.cn/problems/maximum-subarray/
public class Code01_MaximumSubarray {// 動態規劃public static int maxSubArray1(int[] nums) {int n = nums.length;// dp[i] : 子數組必須以i位置的數做結尾,往左能延伸出來的最大累加和int[] dp = new int[n];dp[0] = nums[0];int ans = nums[0];for (int i = 1; i < n; i++) {dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);ans = Math.max(ans, dp[i]);}return ans;}// 空間壓縮public static int maxSubArray2(int[] nums) {int n = nums.length;int ans = nums[0];for (int i = 1, pre = nums[0]; i < n; i++) {pre = Math.max(nums[i], pre + nums[i]);ans = Math.max(ans, pre);}return ans;}// 如下代碼為附加問題的實現// 子數組中找到擁有最大累加和的子數組// 并返回如下三個信息:// 1) 最大累加和子數組的開頭left// 2) 最大累加和子數組的結尾right// 3) 最大累加和子數組的累加和sum// 如果不止一個子數組擁有最大累加和,那么找到哪一個都可以public static int left;public static int right;public static int sum;// 找到擁有最大累加和的子數組// 更新好全局變量left、right、sum// 上游調用函數可以直接使用這三個變量// 相當于返回了三個值public static void extra(int[] nums) {sum = Integer.MIN_VALUE;for (int l = 0, r = 0, pre = Integer.MIN_VALUE; r < nums.length; r++) {if (pre >= 0) {// 吸收前面的累加和有利可圖// 那就不換開頭pre += nums[r];} else {// 吸收前面的累加和已經無利可圖// 那就換開頭pre = nums[r];l = r;}if (pre > sum) {sum = pre;left = l;right = r;}}}}

code2 198. 打家劫舍

// 數組中不能選相鄰元素的最大累加和
// 給定一個數組,可以隨意選擇數字
// 但是不能選擇相鄰的數字,返回能得到的最大累加和
// 測試鏈接 : https://leetcode.cn/problems/house-robber/

dp[i]:表示[0…i]這個范圍上不能選相鄰元素的最大累加和

  1. 不要[i],dp[i-1]
  2. 要[i] a.nums[i] b.dp[i-2]+nums[i]

code1 動態規劃
code2 空間壓縮

package class070;// 數組中不能選相鄰元素的最大累加和
// 給定一個數組,可以隨意選擇數字
// 但是不能選擇相鄰的數字,返回能得到的最大累加和
// 測試鏈接 : https://leetcode.cn/problems/house-robber/
public class Code02_HouseRobber {// 動態規劃public static int rob1(int[] nums) {int n = nums.length;if (n == 1) {return nums[0];}if (n == 2) {return Math.max(nums[0], nums[1]);}// dp[i] : nums[0...i]范圍上可以隨意選擇數字,但是不能選相鄰數,能得到的最大累加和int[] dp = new int[n];dp[0] = nums[0];dp[1] = Math.max(nums[0], nums[1]);for (int i = 2; i < n; i++) {dp[i] = Math.max(dp[i - 1], Math.max(nums[i], dp[i - 2] + nums[i]));}return dp[n - 1];}// 空間壓縮public static int rob2(int[] nums) {int n = nums.length;if (n == 1) {return nums[0];}if (n == 2) {return Math.max(nums[0], nums[1]);}int prepre = nums[0];int pre = Math.max(nums[0], nums[1]);for (int i = 2, cur; i < n; i++) {cur = Math.max(pre, Math.max(nums[i], prepre + nums[i]));prepre = pre;pre = cur;}return pre;}}

code3 918. 環形子數組的最大和

// 環形數組的子數組最大累加和
// 給定一個數組nums,長度為n
// nums是一個環形數組,下標0和下標n-1是連在一起的
// 返回環形數組中,子數組最大累加和
// 測試鏈接 : https://leetcode.cn/problems/maximum-sum-circular-subarray/

(1) 答案不被隔斷,同1普通數組,最大累加和maxSum
(2) 答案被隔斷,整體累加和all-最小累加和minSum
兩者取較大即為答案

package class070;// 環形數組的子數組最大累加和
// 給定一個數組nums,長度為n
// nums是一個環形數組,下標0和下標n-1是連在一起的
// 返回環形數組中,子數組最大累加和
// 測試鏈接 : https://leetcode.cn/problems/maximum-sum-circular-subarray/
public class Code03_MaximumSumCircularSubarray {public static int maxSubarraySumCircular(int[] nums) {int n = nums.length, all = nums[0], maxsum = nums[0], minsum = nums[0];for (int i = 1, maxpre = nums[0], minpre = nums[0]; i < n; i++) {all += nums[i];maxpre = Math.max(nums[i], nums[i] + maxpre);maxsum = Math.max(maxsum, maxpre);minpre = Math.min(nums[i], nums[i] + minpre);minsum = Math.min(minsum, minpre);}// 1) maxsum// 2) all - minsumreturn all == minsum ? maxsum : Math.max(maxsum, all - minsum);}}

code4 213. 打家劫舍 II

// 環形數組中不能選相鄰元素的最大累加和
// 給定一個數組nums,長度為n
// nums是一個環形數組,下標0和下標n-1是連在一起的
// 可以隨意選擇數字,但是不能選擇相鄰的數字
// 返回能得到的最大累加和
// 測試鏈接 : https://leetcode.cn/problems/house-robber-ii/

思路:
不要[0]位置 [1…n-1]
要[0]位置 nums[0] + [2…n-2]

package class070;// 環形數組中不能選相鄰元素的最大累加和
// 給定一個數組nums,長度為n
// nums是一個環形數組,下標0和下標n-1是連在一起的
// 可以隨意選擇數字,但是不能選擇相鄰的數字
// 返回能得到的最大累加和
// 測試鏈接 : https://leetcode.cn/problems/house-robber-ii/
public class Code04_HouseRobberII {public static int rob(int[] nums) {int n = nums.length;if (n == 1) {return nums[0];}return Math.max(best(nums, 1, n - 1), nums[0] + best(nums, 2, n - 2));}// nums[l....r]范圍上,沒有環形的概念// 返回 : 可以隨意選擇數字,但不能選擇相鄰數字的情況下,最大累加和public static int best(int[] nums, int l, int r) {if (l > r) {return 0;}if (l == r) {return nums[l];}if (l + 1 == r) {return Math.max(nums[l], nums[r]);}int prepre = nums[l];int pre = Math.max(nums[l], nums[l + 1]);for (int i = l + 2, cur; i <= r; i++) {cur = Math.max(pre, nums[i] + Math.max(0, prepre));prepre = pre;pre = cur;}return pre;}}

code5 2560. 打家劫舍 IV

// 打家劫舍 IV
// 沿街有一排連續的房屋。每間房屋內都藏有一定的現金
// 現在有一位小偷計劃從這些房屋中竊取現金
// 由于相鄰的房屋裝有相互連通的防盜系統,所以小偷不會竊取相鄰的房屋
// 小偷的 竊取能力 定義為他在竊取過程中能從單間房屋中竊取的 最大金額
// 給你一個整數數組 nums 表示每間房屋存放的現金金額
// 第i間房屋中放有nums[i]的錢數
// 另給你一個整數k,表示小偷需要竊取至少 k 間房屋
// 返回小偷需要的最小竊取能力值
// 測試鏈接 : https://leetcode.cn/problems/house-robber-iv/

二分答案法
能力[min,max]有單調性
布爾函數判斷能力值給定,是否能偷夠k間

dp[i]:[0…i]范圍上不偷相鄰房間并且有能力要求的最大間數

不偷[i],dp[i-1]
能力大于[i],偷[i] dp[i-2]+1
偷不了[i] dp[i-2]

貪心優化:
能偷就偷,偷了就跳過,
盡早偷,留下更大的區間

code1 動態規劃
code2 空間壓縮
code3 貪心優化

package class070;// 打家劫舍 IV
// 沿街有一排連續的房屋。每間房屋內都藏有一定的現金
// 現在有一位小偷計劃從這些房屋中竊取現金
// 由于相鄰的房屋裝有相互連通的防盜系統,所以小偷不會竊取相鄰的房屋
// 小偷的 竊取能力 定義為他在竊取過程中能從單間房屋中竊取的 最大金額
// 給你一個整數數組 nums 表示每間房屋存放的現金金額
// 第i間房屋中放有nums[i]的錢數
// 另給你一個整數k,表示小偷需要竊取至少 k 間房屋
// 返回小偷需要的最小竊取能力值
// 測試鏈接 : https://leetcode.cn/problems/house-robber-iv/
public class Code05_HouseRobberIV {public static int minCapability(int[] nums, int k) {int n = nums.length, l = nums[0], r = nums[0];for (int i = 1; i < n; i++) {l = Math.min(l, nums[i]);r = Math.max(r, nums[i]);}// l....rint m, ans = 0;while (l <= r) {m = (l + r) / 2;if (mostRob1(nums, n, m) >= k) {ans = m;r = m - 1;} else {l = m + 1;}}return ans;}// 盜賊能力為ability時// 返回盜賊最多能竊取多少間房屋// 注意限制 : 不能竊取相鄰房屋public static int mostRob1(int[] nums, int n, int ability) {if (n == 1) {return nums[0] <= ability ? 1 : 0;}if (n == 2) {return (nums[0] <= ability || nums[1] <= ability) ? 1 : 0;}int[] dp = new int[n];dp[0] = nums[0] <= ability ? 1 : 0;dp[1] = (nums[0] <= ability || nums[1] <= ability) ? 1 : 0;for (int i = 2; i < n; i++) {dp[i] = Math.max(dp[i - 1], (nums[i] <= ability ? 1 : 0) + dp[i - 2]);}return dp[n - 1];}// 繼續空間壓縮優化public static int mostRob2(int[] nums, int n, int ability) {if (n == 1) {return nums[0] <= ability ? 1 : 0;}if (n == 2) {return (nums[0] <= ability || nums[1] <= ability) ? 1 : 0;}int prepre = nums[0] <= ability ? 1 : 0;int pre = (nums[0] <= ability || nums[1] <= ability) ? 1 : 0;for (int i = 2, cur; i < n; i++) {cur = Math.max(pre, (nums[i] <= ability ? 1 : 0) + prepre);prepre = pre;pre = cur;}return pre;}// 繼續貪心優化public static int mostRob3(int[] nums, int n, int ability) {int ans = 0;for (int i = 0; i < n; i++) {if (nums[i] <= ability) {ans++;i++;}}return ans;}}

code6 面試題 17.24. 最大子矩陣

// 子矩陣最大累加和問題
// 給定一個二維數組grid,找到其中子矩陣的最大累加和
// 返回擁有最大累加和的子矩陣左上角和右下角坐標
// 如果有多個子矩陣都有最大累加和,返回哪一個都可以
// 測試鏈接 : https://leetcode.cn/problems/max-submatrix-lcci/

package class070;import java.util.Arrays;// 子矩陣最大累加和問題
// 給定一個二維數組grid,找到其中子矩陣的最大累加和
// 返回擁有最大累加和的子矩陣左上角和右下角坐標
// 如果有多個子矩陣都有最大累加和,返回哪一個都可以
// 測試鏈接 : https://leetcode.cn/problems/max-submatrix-lcci/
public class Code06_MaximumSubmatrix {// 如果行和列的規模都是n,時間復雜度O(n^3),最優解了public static int[] getMaxMatrix(int[][] grid) {int n = grid.length;int m = grid[0].length;int max = Integer.MIN_VALUE;int a = 0, b = 0, c = 0, d = 0;int[] nums = new int[m];for (int up = 0; up < n; up++) {Arrays.fill(nums, 0);for (int down = up; down < n; down++) {// 如下代碼就是題目1的附加問題 :// 子數組中找到擁有最大累加和的子數組for (int l = 0, r = 0, pre = Integer.MIN_VALUE; r < m; r++) {nums[r] += grid[down][r];if (pre >= 0) {pre += nums[r];} else {pre = nums[r];l = r;}if (pre > max) {max = pre;a = up;b = l;c = down;d = r;}}}}return new int[] { a, b, c, d };}}

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

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

相關文章

【Docker】Docker Compose,yml 配置指令參考的詳細講解

作者簡介&#xff1a; 辭七七&#xff0c;目前大二&#xff0c;正在學習C/C&#xff0c;Java&#xff0c;Python等 作者主頁&#xff1a; 七七的個人主頁 文章收錄專欄&#xff1a; 七七的閑談 歡迎大家點贊 &#x1f44d; 收藏 ? 加關注哦&#xff01;&#x1f496;&#x1f…

基于c++版數據結構基于數組棧改-Python思維總結

##棧部分-&#xff08;疊貓貓&#xff09; ##抽象數據類型棧的定義&#xff1a;是一種遵循先入后出的邏輯的線性數據結構。 換種方式去理解這種數據結構如果我們在一摞盤子中取到下面的盤子&#xff0c;我們首先要把最上面的盤子依次拿走&#xff0c;才可以繼續拿下面的盤子&…

【Java期末復習資料】(2)常見例題 //持續更新

本文章主要是常見例題&#xff0c;解析不會太詳細&#xff0c;有問題、不會的可以給我發消息哦&#xff0c;后續會出模擬卷 常見例題&#xff1a; 1.下列跟Java技術平臺有關的是&#xff08;ABD&#xff09; A.JVM B.JDK C.JPN D.JRE 2.面向對象的特征包括&#xff08;ACD&…

wxPython的控件tree

wxPython樹控件介紹 樹&#xff08;tree&#xff09;是一種通過層次結構展示信息的控件&#xff0c;如下圖所示是樹控件示例&#xff0c;左窗口中是樹控件&#xff0c;在wxPython中樹控件類是wx.TreeCtrl。 wx.TreeCtrl常用的方法有 AddRoot(text, image-1, selImage-1, data…

在Deepin中安裝x11vnc工具并結合內網穿透軟件實現遠程訪問桌面

文章目錄 1. 安裝x11vnc2. 本地遠程連接測試3. Deepin安裝Cpolar4. 配置公網遠程地址5. 公網遠程連接Deepin桌面6. 固定連接公網地址7. 固定公網地址連接測試 x11vnc是一種在Linux系統中實現遠程桌面控制的工具&#xff0c;它的原理是通過X Window系統的協議來實現遠程桌面的展…

P4 Qt如何添加qss樣式表文件和添加圖片資源

目錄 前言 01 添加圖片資源文件 02 添加qss文件 前言 &#x1f3ac; 個人主頁&#xff1a;ChenPi &#x1f43b;推薦專欄1: 《C_ChenPi的博客-CSDN博客》??? &#x1f525; 推薦專欄2: 《Qt基礎_ChenPi的博客-CSDN博客》??? &#x1f33a;本篇簡介 &#xff1a;這一章…

JVM Optimization Learning(六)

目錄 一、JVM Optimization 1、Shenandoah Shenandoah的使用方法 2、ZGC ZGC的版本更迭 ZGC的使用方法 ZGC的參數設置 3、JMH測試GC性能 一、JVM Optimization 1、Shenandoah Shenandoah是由Red Hat開發的一款低延遲的垃圾收集器&#xff0c;Shenandoah并發執行大部分…

機器人純阻抗控制接觸剛性環境(阻尼影響因素)

問題描述 在機器人學中&#xff0c;阻抗控制是一種常用的控制策略&#xff0c;用于管理機器人在與環境交互時的運動和力。阻抗控制背后的關鍵概念是將環境視為導納&#xff0c;而將機器人視為阻抗。 純阻抗控制接觸剛性環境時&#xff0c;機器人的行為方式主要受其阻抗參數的…

數據結構和算法專題---6、定時算法與應用

本章我們會對定時算法做個簡單介紹&#xff0c;包括常用的定時算法&#xff08;最小堆、時間輪&#xff09;的概述、實現方式、典型場景做個說明。 概述 系統或者項目中難免會遇到各種需要自動去執行的任務&#xff0c;實現這些任務的手段也多種多樣&#xff0c;如操作系統的…

【C++】使用“/**/“進行注釋的好處

2023年12月10日&#xff0c;周日晚上 我今天下午看Google Chrome的源碼時&#xff0c;才發現"/**/"原來還能這么用 使用"/**/"的好處就是&#xff0c;可以在任何地方進行注釋&#xff0c;哪怕是參數列表 void CircularWindow::enterEvent(QEvent *event/…

【Python】判斷域名是否合法

python判斷域名是否合法|校驗域名 域名以點號分隔成多個字符串。單個字符串由各國文字的特定字符集、字母、數字、連字符&#xff08;-&#xff09;組成&#xff0c;字母不區分大小寫&#xff0c;連字符&#xff08;-&#xff09;不得出現在字符串的頭部或者尾部。單個字符串長…

GitHub Enterprise Server 添加代碼安全、自動化功能

GitHub的軟件更新用于管理私有服務器上的存儲庫&#xff0c;具有GitHub容器注冊訪問、Dependabot安全警報和更新以及可重用工作流的特性。 GitHub Enterprise Server 3.5是GitHub用于托管和管理私有服務器上存儲庫的最新版本&#xff0c;它引入了新的代碼安全特性&#xff0c;新…

Helm 常用運維命令

原理參考 ## https://blog.csdn.net/knight_zhou/article/details/122079292 常用運維命令 helm search: ??搜索charthelm pull: ???下載chart到本地目錄查看helm install: ??上傳chart到Kuberneteshelm list: ????列出已發布的chart

【開源】基于Vue和SpringBoot的車險自助理賠系統

項目編號&#xff1a; S 018 &#xff0c;文末獲取源碼。 \color{red}{項目編號&#xff1a;S018&#xff0c;文末獲取源碼。} 項目編號&#xff1a;S018&#xff0c;文末獲取源碼。 目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、功能模塊2.1 數據中心模塊2.2 角色管理模塊2.3 車…

Maven基礎

目錄 Maven坐標 坐標簡介 主要組成 Maven依賴管理 配置依賴 依賴簡介 配置依賴 依賴傳遞 依賴傳遞簡介 排除依賴 依賴范圍 生命周期 生命周期簡介 執行指定生命周期 Maven坐標 坐標簡介 Maven中的坐標是資源的唯一標識&#xff0c;通過該坐標可以唯一定位資…

Redis交互速度慢,CPU占用100%,集群方案,報錯等問題

后續補充結論 仔細查看前輩們堆的代碼中發現居然調用了大量key*查詢&#xff0c;導致走的遍歷非常慢&#xff01;因為這相當與全部數據量遍歷&#xff0c;即這個原因導致了查詢速度與數據量成正比&#xff0c;推測也是CPU占用高的元兇&#xff1b;即使加上key前綴再匹配*也會走…

Python開發運維:Python調用K8S API實現資源管理

目錄 一、實驗 1.Python操作K8S API獲取資源 2.Python操作K8S API創建deployment資源 3.Python操作K8S API刪除k8s資源 4.Python操作K8S API修改k8s資源 5.Python操作K8S API查看k8s資源 二、問題 1.Windows11安裝kubernetes報錯 2.Python通過調用哪些方法實現Pod和De…

在SpringData JPA 中實現對持久層的操作

1.導入依賴 hibernate 這個依賴自帶實現JPA接口 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><depen…

TCP三次握手、四次揮手及狀態轉換詳解

1.什么是TCP協議&#xff1f; 傳輸控制協議&#xff08;TCP&#xff0c;Transmission Control Protocol&#xff09;是一種面向連接的、可靠的、基于字節流的傳輸層通信協議&#xff0c;位于網絡OSI七層模型的第四層&#xff0c;IP協議一起工作&#xff0c;TCP層是位于IP層之上…

(Spring學習07)Spring之啟動刷新過程源碼解析

概述 通常&#xff0c;我們說的Spring啟動&#xff0c;就是構造ApplicationContext對象以及調用refresh()方法的過程。 首先&#xff0c;Spring啟動過程主要做了這么幾件事情&#xff1a; 構造一個BeanFactory對象解析配置類&#xff0c;得到BeanDefinition&#xff0c;并注冊…