成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

最大子序和,又貪心又DP

開發 前端
本題的貪心思路其實并不好想,這也進一步驗證了,別看貪心理論很直白,有時候看似是常識,但貪心的題目一點都不簡單!

[[434714]]

從本題開始,貪心題目都比較難了!

 最大子序和

力扣題目鏈接:https://leetcode-cn.com/problems/maximum-subarray

給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。

示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4] 輸出: 6 解釋: 連續子數組 [4,-1,2,1] 的和最大,為 6。

暴力解法

暴力解法的思路,第一層for 就是設置起始位置,第二層for循環遍歷數組尋找最大值

時間復雜度:O(n^2) 空間復雜度:O(1)

  1. class Solution { 
  2. public
  3.     int maxSubArray(vector<int>& nums) { 
  4.         int result = INT32_MIN; 
  5.         int count = 0; 
  6.         for (int i = 0; i < nums.size(); i++) { // 設置起始位置 
  7.             count = 0; 
  8.             for (int j = i; j < nums.size(); j++) { // 每次從起始位置i開始遍歷尋找最大值 
  9.                 count += nums[j]; 
  10.                 result = count > result ? count : result; 
  11.             } 
  12.         } 
  13.         return result; 
  14.     } 
  15. }; 

以上暴力的解法C++勉強可以過,其他語言就不確定了。

貪心解法

貪心貪的是哪里呢?

如果 -2 1 在一起,計算起點的時候,一定是從1開始計算,因為負數只會拉低總和,這就是貪心貪的地方!

局部最優:當前“連續和”為負數的時候立刻放棄,從下一個元素重新計算“連續和”,因為負數加上下一個元素 “連續和”只會越來越小。

全局最優:選取最大“連續和”

局部最優的情況下,并記錄最大的“連續和”,可以推出全局最優。

從代碼角度上來講:遍歷nums,從頭開始用count累積,如果count一旦加上nums[i]變為負數,那么就應該從nums[i+1]開始從0累積count了,因為已經變為負數的count,只會拖累總和。

這相當于是暴力解法中的不斷調整最大子序和區間的起始位置。

那有同學問了,區間終止位置不用調整么?如何才能得到最大“連續和”呢?

區間的終止位置,其實就是如果count取到最大值了,及時記錄下來了。例如如下代碼:

  1. if (count > result) result = count

這樣相當于是用result記錄最大子序和區間和(變相的算是調整了終止位置)。

如動畫所示:

圖片

最大子序和

紅色的起始位置就是貪心每次取count為正數的時候,開始一個區間的統計。

那么不難寫出如下C++代碼(關鍵地方已經注釋)

  1. class Solution { 
  2. public
  3.     int maxSubArray(vector<int>& nums) { 
  4.         int result = INT32_MIN; 
  5.         int count = 0; 
  6.         for (int i = 0; i < nums.size(); i++) { 
  7.             count += nums[i]; 
  8.             if (count > result) { // 取區間累計的最大值(相當于不斷確定最大子序終止位置) 
  9.                 result = count
  10.             } 
  11.             if (count <= 0) count = 0; // 相當于重置最大子序起始位置,因為遇到負數一定是拉低總和 
  12.         } 
  13.         return result; 
  14.     } 
  15. }; 

時間復雜度:O(n) 空間復雜度:O(1)

當然題目沒有說如果數組為空,應該返回什么,所以數組為空的話返回啥都可以了。

不少同學認為 如果輸入用例都是-1,或者 都是負數,這個貪心算法跑出來的結果是0, 這是又一次證明腦洞模擬不靠譜的經典案例,建議大家把代碼運行一下試一試,就知道了,也會理解 為什么 result 要初始化為最小負數了。

動態規劃

當然本題還可以用動態規劃來做,當前「代碼隨想錄」主要講解貪心系列,后續到動態規劃系列的時候會詳細講解本題的dp方法。

那么先給出我的dp代碼如下,有時間的錄友可以提前做一做:

  1. class Solution { 
  2. public
  3.     int maxSubArray(vector<int>& nums) { 
  4.         if (nums.size() == 0) return 0; 
  5.         vector<int> dp(nums.size(), 0); // dp[i]表示包括i之前的最大連續子序列和 
  6.         dp[0] = nums[0]; 
  7.         int result = dp[0]; 
  8.         for (int i = 1; i < nums.size(); i++) { 
  9.             dp[i] = max(dp[i - 1] + nums[i], nums[i]); // 狀態轉移公式 
  10.             if (dp[i] > result) result = dp[i]; // result 保存dp[i]的最大值 
  11.         } 
  12.         return result; 
  13.     } 
  14. }; 

時間復雜度:O(n) 空間復雜度:O(n)

總結

本題的貪心思路其實并不好想,這也進一步驗證了,別看貪心理論很直白,有時候看似是常識,但貪心的題目一點都不簡單!

后續將介紹的貪心題目都挺難的,哈哈,所以貪心很有意思,別小看貪心!

其他語言版本

Java

  1. class Solution { 
  2.     public int maxSubArray(int[] nums) { 
  3.         if (nums.length == 1){ 
  4.             return nums[0]; 
  5.         } 
  6.         int sum = Integer.MIN_VALUE; 
  7.         int count = 0; 
  8.         for (int i = 0; i < nums.length; i++){ 
  9.             count += nums[i]; 
  10.             sum = Math.max(sumcount); // 取區間累計的最大值(相當于不斷確定最大子序終止位置) 
  11.             if (count <= 0){ 
  12.                 count = 0; // 相當于重置最大子序起始位置,因為遇到負數一定是拉低總和 
  13.             } 
  14.         } 
  15.        return sum
  16.     } 
  1. // DP 方法 
  2. class Solution { 
  3.     public int maxSubArray(int[] nums) { 
  4.         int ans = Integer.MIN_VALUE; 
  5.         int[] dp = new int[nums.length]; 
  6.         dp[0] = nums[0]; 
  7.         ans = dp[0]; 
  8.  
  9.         for (int i = 1; i < nums.length; i++){ 
  10.             dp[i] = Math.max(dp[i-1] + nums[i], nums[i]); 
  11.             ans = Math.max(dp[i], ans); 
  12.         } 
  13.  
  14.         return ans; 
  15.     } 

Python

  1. class Solution: 
  2.     def maxSubArray(self, nums: List[int]) -> int
  3.         result = -float('inf'
  4.         count = 0 
  5.         for i in range(len(nums)): 
  6.             count += nums[i] 
  7.             if count > result: 
  8.                 result = count 
  9.             if count <= 0: 
  10.                 count = 0 
  11.         return result 

Go

  1. func maxSubArray(nums []intint { 
  2.     maxSum := nums[0] 
  3.     for i := 1; i < len(nums); i++ { 
  4.         if nums[i] + nums[i-1] > nums[i] { 
  5.             nums[i] += nums[i-1] 
  6.         } 
  7.         if nums[i] > maxSum { 
  8.             maxSum = nums[i] 
  9.         } 
  10.     } 
  11.     return maxSum 

 

責任編輯:姜華 來源: 代碼隨想錄
相關推薦

2023-07-18 19:11:21

配置信令系統

2021-09-09 18:12:22

內存分段式網絡

2019-07-18 09:17:19

Kafka消息隊列服務器

2014-07-23 10:19:02

小米4

2017-12-28 10:44:08

JavaScript瀏覽器網頁

2022-03-04 12:09:25

SQL數據量多表查詢

2013-12-06 10:11:48

Windows 8Windows 7Windows 8.1

2014-12-04 09:58:59

PHP

2018-03-05 10:27:47

電腦卡頓舊電腦

2019-05-27 08:09:43

WiFi無線信道上網

2022-01-04 14:21:56

Vite組件React

2020-12-19 10:46:20

黑客網絡安全網絡攻擊

2024-12-04 13:54:19

pnpm存儲項目

2021-12-27 13:57:34

Vite 工具項目

2019-11-11 13:40:45

Python 開發編程語言

2018-08-15 14:02:19

ODCCIT領域液冷

2023-12-19 08:28:34

RabbitMQ消息隊列架構

2022-12-05 14:35:30

2023-03-31 09:09:16

OKRKPIKR

2019-08-06 08:47:18

運營商流量套餐4G服務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲激情第一页 | 91亚洲一区| 欧美八区 | 在线成人 | 国产免费av在线 | 中文字幕精品一区二区三区精品 | 成在线人视频免费视频 | jizz18国产 | 91视频88av | 免费毛片网站 | 国产成人av电影 | 国产色婷婷精品综合在线播放 | 久久久久九九九九 | 99爱免费| 国产乱码精品一区二区三区忘忧草 | 国产精品久久一区二区三区 | 亚洲视频精品在线 | 欧美日韩精品免费 | 午夜影院在线 | 欧美在线视频一区 | 特一级毛片 | 国产人成精品一区二区三 | 日韩成人精品视频 | 日韩在线观看 | 91高清免费观看 | 激情欧美日韩一区二区 | 欧美精品一区二区三区四区 在线 | 性做久久久久久免费观看欧美 | 久久亚洲综合 | 日本午夜网 | aaaa一级毛片 | 一区二区三区在线免费 | 日韩一区二区三区四区五区六区 | a级片在线观看 | 国产一区二区三区精品久久久 | 澳门永久av免费网站 | 国产99视频精品免费视频7 | 久久精品国产99国产精品亚洲 | 国产精品久久久久久久久久软件 | 欧美高清hd | 日韩精品一区二区三区中文在线 |