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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【LeetCode】LeetCode之乘积最大子数组——枚举+动态规划+Kadane算法

發布時間:2024/10/5 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【LeetCode】LeetCode之乘积最大子数组——枚举+动态规划+Kadane算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

🔏1.題目描述

給你一個整數數組 nums ,請你找出數組中乘積最大的連續子數組(該子數組中至少包含一個數字),并返回該子數組所對應的乘積。

📜示例 1:

輸入: [2,3,-2,4]
輸出: 6
解釋: 子數組 [2,3] 有最大乘積 6。

📜示例 2:

輸入: [-2,0,-1]
輸出: 0
解釋: 結果不能為 2, 因為 [-2,-1] 不是子數組。

🍀2.暴力解法

該題最簡單的無非就是暴力解法,通過兩次for循環枚舉出所有子數組,然后維護一個最大值即可。

/*** 暴力解法* 時間復雜度:O(n^2)* 空間復雜度:O(1)*/public int maxProduct(int[] nums) {int maxProduct = nums[0];int size = nums.length;int curProduct = 1;for (int i = 0; i < size; i++) {for (int j = i; j < size; j++) {curProduct = curProduct * nums[j];maxProduct = Math.max(curProduct, maxProduct);}curProduct = 1;}return maxProduct;}

復雜度分析

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

提交到LeetCode擦邊界通過了,本以為時間復雜度O(n^2)一般來說很難通過。

🍀3.動態規劃

動態規劃核心三要素:

  • 階段:分解子問題,子問題與原問題求解過程相同
  • 狀態:每個階段都有一個或多個狀態
  • 決策:根據當前的決策,確定下一階段的狀態

那么怎么分析該問題呢?如果讓你求f(n),你覺得這個f(n)是怎么從推導過來的?
因為該題存在負負得正的情況,所以這種情況也要考慮;試想如果要求f(n)的乘積最大,是不是分為如下三種情況:

  • 如果當前元素a為正數,那么如果要求f(n)最大,是不是只要確保f(n-1)最大即可
    如果當前元素a為負數,那么如果要求f(n)最大,是不是只要保證f(n-1)最小即可,【(-3 * -10 = 30) ( -3 * -100 = 300)
    第三種可能就是正負不一致,那最大值就是a

所以它的遞推關系式就是

Fmax(i) = max{Fmax(i-1)*a,Fmin(i-1)*a, a}
Fmin(i) = max{Fmax(i-1)*a, Fmin(i - 1)*a, a}

所以需要兩個dp數組進行維護。

/*** 動態規劃* 時間復雜度:O(n)* 空間復雜度:O(n)*/public int maxProduct2(int[] nums) {int size = nums.length;int[] maxDP = new int[nums.length];int[] minDP = new int[nums.length];int mp = nums[0];maxDP[0] = minDP[0] = mp;for (int i = 1; i < size; i++) {maxDP[i] = Math.max(Math.max(maxDP[i - 1] * nums[i], minDP[i - 1] * nums[i]), nums[i]);minDP[i] = Math.min(Math.min(maxDP[i - 1] * nums[i], minDP[i - 1] * nums[i]), nums[i]);mp = Math.max(mp, maxDP[i]);}return mp;}

復雜度分析:

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

提交到LeetCode


那么有沒有什么辦法將空間優化到O(1)呢?

🍀3.Kadane算法

其實本質上Kadane算法還是使用的是動態規劃思想,說白了它就是將動態規劃的空間復雜度優化到了O(1),本質上就是動態規劃。

上述動態規劃是使用兩個dp數組作為記憶集的,我們會發現每次求解出的當前狀態的結果只會被下次使用一次。所以可以通過變量每次保存當前階段的結果,然后當求解出下一階段的結果時,會使用該變量一次,最后計算出了下一階段得結果,最后賦值給我當前變量即可。循環使用!

/*** Kadane算法【動態規劃優化空間】* 時間復雜度:O(n)* 空間復雜度:O(1)*/public int maxProduct3(int[] nums) {int size = nums.length;int mp = nums[0];int curMax1, curMin1;curMax1 = curMin1 = mp;for (int i = 1; i < size; i++) {int cur = curMax1;curMax1 = Math.max(Math.max(curMax1 * nums[i], curMin1 * nums[i]), nums[i]);curMin1 = Math.min(Math.min(cur * nums[i], curMin1 * nums[i]), nums[i]);mp = Math.max(mp, curMax1);}return mp;}

復雜度分析:

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


總結

以上是生活随笔為你收集整理的【LeetCode】LeetCode之乘积最大子数组——枚举+动态规划+Kadane算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。