最大子序和 --動態規劃

前面寫了一些算法題,可是寫到後面,發現不怎麼系統起來,因此從這一篇開始,咱們先着重介紹一下動態規劃算法!算法

咱們以題目開門見山.swift

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

示例:app

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

 

解法一:動態規劃思想spa

思路code

  • 首先對數組進行遍歷,當前最大連續子序列和爲sum,結果爲results
  • 若是sum > 0,則說明sum對結果有增益效果,則sum保留並加上當前遍歷數字
  • 若是sum <= 0,則說明sum對結果無增益效果,須要捨棄,則sum直接更新爲當前遍歷數字
  • 每次比較sum 和 results的大小,將最大值置爲results,遍歷結束後返回結果results
  • 時間複雜度爲O(n)

代碼swiftblog

func maxSubArray(_ nums: [Int]) -> Int {
    var results: Int = nums[0]
    var sum = 0
    for i in 0..<nums.count {
        if sum > 0 {
            sum = sum + nums[i]
        } else {
            sum = nums[i]
        }
        results = sum > results ? sum : results
    }
    return results
}

運行結果以下:class

 

解法二:動態規劃思想遍歷

思路im

動態規劃,用dp[i]表示以i結尾的最大子序列和。初始化值dp[0] = nums[0],而後從第二個數開始遍歷

  • 若是當前數加上前一個最大序列和大於當前數,則將當前數加到序列和中,nums[i] + dp[i - 1] > nums[i],則dp[i] = nums[i] + dp[i - 1];
  • 反之以當前數結尾的最大序列和即爲dp[i] = nums[i -1]

 而後判斷以當前結尾的最大序列和是否大於最大序列和。

時間複雜度爲O(n)

空間複雜度爲O(n)

代碼

func maxSubArray(_ nums: [Int]) -> Int {
    guard nums.count > 0 else {return -1}
    var results: Int = nums[0]
    var dp = [Int]()
    dp.append(nums[0])
    for i in 1..<nums.count {
        if nums[i] + dp[i - 1] >= nums[i] {
            dp.append(nums[i] + dp[i - 1])
        } else {
            dp.append(nums[i])
        }
        if dp[i] > results {
            results = dp[i] }
    }
    return results
}

記住swift中不能直接用「=」賦值,用append增長元素

 

以上就是動態規劃的思想和代碼,你們能夠寫下,但願對你們有所幫助!!!當講到分治思想,再會增長分治思想解決問題!

相關文章
相關標籤/搜索