zoukankan      html  css  js  c++  java
  • [Swift]LeetCode188. 买卖股票的最佳时机 IV | Best Time to Buy and Sell Stock IV

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/10179523.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    Say you have an array for which the ith element is the price of a given stock on day i.

    Design an algorithm to find the maximum profit. You may complete at most ktransactions.

    Note:
    You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

    Example 1:

    Input: [2,4,1], k = 2
    Output: 2
    Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.
    

    Example 2:

    Input: [3,2,6,5,0,3], k = 2
    Output: 7
    Explanation: Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4.
                 Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.

    给定一个数组,它的第 i 个元素是一支给定的股票在第 天的价格。

    设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。

    注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

    示例 1:

    输入: [2,4,1], k = 2
    输出: 2
    解释: 在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。
    

    示例 2:

    输入: [3,2,6,5,0,3], k = 2
    输出: 7
    解释: 在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。
         随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。

    48ms
     1 class Solution {
     2     func maxProfit(_ k: Int, _ prices: [Int]) -> Int {
     3 guard prices.count > 1, k > 0 else { return 0 }
     4     let n = prices.count
     5     
     6     if k >= (n / 2) {
     7         var res = 0
     8         for i in 1..<n {
     9             if (prices[i] > prices[i-1]) {
    10                 res += prices[i] - prices[i-1]
    11             }
    12             
    13         }
    14         return res
    15     }
    16         var mp = [[Int]](repeating: [Int](repeating: 0, count: k + 1), count: prices.count)
    17     for i in 1...k {
    18         var localMax = -prices[0]
    19         for j in 1..<n {
    20             mp[j][i] = max(mp[j-1][i], prices[j]+localMax)
    21             localMax = max(localMax, mp[j-1][i-1]-prices[j])
    22         }
    23     }
    24     return mp[prices.count-1][k]
    25     }
    26 }

    52ms

     1 class Solution {
     2     func maxProfit(_ k: Int, _ prices: [Int]) -> Int {
     3 
     4         var n = prices.count
     5         if n < 2 || k == 0 { return 0 }
     6         if k >= n { return maxProfit(prices)}
     7         var l = Array(repeating: 0, count: k+1)
     8         var g = Array(repeating: 0, count: k+1)
     9         for i in 0..<n-1 {
    10             var diff = prices[i+1] - prices[i]
    11             for j in stride(from: k, through: 1, by: -1){
    12                 l[j] = max(g[j-1] + max(diff, 0), l[j] + diff)
    13                 g[j] = max(g[j], l[j])
    14             }
    15         }
    16         
    17 
    18         return g[k];
    19 
    20     }
    21     func maxProfit(_ prices: [Int]) -> Int {
    22         var res = 0
    23         for i in 1..<prices.count {
    24             res += max(0, prices[i] - prices[i-1])
    25         }
    26         return res
    27     }
    28 }

    120ms

     1 class Solution {
     2     func maxProfit(_ k: Int, _ prices: [Int]) -> Int {
     3         if k == 0 || prices.count < 2 {
     4             return 0
     5         }
     6         
     7         let count = prices.count
     8         if count <= k * 2 + 1 {
     9             return maxProfitUn(prices)
    10         }
    11         
    12         if k == 2 {
    13             return maxProfitTwo(prices)
    14         }
    15         
    16         var mustSell = Array(repeating: Array(repeating: 0 , count: k+1), count: count)
    17         var globalSell = Array(repeating: Array(repeating: 0, count: k+1), count: count)
    18         
    19         for j in 1...k {
    20             for i in 1..<count {
    21                 var profit = prices[i] - prices[i-1]
    22                 profit = max(profit, 0)
    23                 mustSell[i][j] = max(globalSell[i-1][j-1] + profit, mustSell[i-1][j] + prices[i] - prices[i-1])
    24                 globalSell[i][j] = max(globalSell[i-1][j], mustSell[i][j])
    25             }
    26         }
    27         
    28         return globalSell[count-1][k]
    29     }
    30     
    31     func maxProfitUn(_ prices : [Int]) -> Int {
    32         if prices.count < 2 {
    33             return 0
    34         }
    35         
    36         let count = prices.count
    37         var res = 0
    38         for i in 1..<count {
    39             if prices[i] > prices[i-1] {
    40                 res += prices[i] - prices[i-1]
    41             }
    42         }
    43         
    44         return res
    45     }
    46     
    47     func maxProfitTwo(_ prices : [Int]) -> Int {
    48         if prices.count < 2 {
    49             return 0
    50         }
    51         
    52         let count = prices.count
    53         
    54         var curMax = 0
    55         
    56         var dp = Array(repeating: 0, count: count)
    57         
    58         var curMin = prices[0]
    59         for i in 1..<count {
    60             curMax = max(curMax, prices[i] - curMin)
    61             curMin = min(curMin, prices[i])
    62             dp[i] = curMax
    63         }
    64         
    65         var maxPrice = prices[count - 1]
    66         curMax = 0
    67         var dp2 = Array(repeating: 0, count: count)
    68         for i in stride(from: count-1, to: -1, by: -1) {
    69             curMax = max(curMax, maxPrice - prices[i])
    70             maxPrice = max(maxPrice, prices[i])
    71             dp2[i] = curMax
    72         }
    73         
    74         curMax = 0
    75         for i in stride(from: count-1, to: 0, by: -1) {
    76             curMax = max(curMax, dp[i] + dp2[i])
    77         }
    78         
    79         return curMax
    80     }
    81 }

    704ms

      1 class Solution {
      2     
      3     struct Section {
      4         
      5         var start: Int
      6         var end: Int
      7         var hasProfit: Bool
      8         var countedProfit: Int?
      9         var countedStart: Int?
     10         var countedEnd: Int?
     11         var countedHasProfit: Bool?
     12         
     13         init() {
     14             self.start = 0
     15             self.end = 0
     16             self.hasProfit = false
     17         }
     18         
     19         init(start: Int, end: Int, hasProfit: Bool) {
     20             
     21             self.start = start
     22             self.end = end
     23             self.hasProfit = hasProfit
     24         }
     25     }
     26     
     27     func maxProfit(_ k: Int, _ prices: [Int]) -> Int {
     28         
     29         if prices.count < 2 {
     30             return 0
     31         }
     32         
     33         var totalProfit = 0
     34         
     35 
     36         var subRange:[Section] = []
     37         
     38         subRange.append(Section.init(start: 0, end: prices.count-1, hasProfit: false))
     39         
     40         for _ in 0..<k {
     41             
     42             var maxProfit = 0
     43             var tmpProfit = 0
     44             
     45             var maxIndex = -1
     46             
     47             var maxSection = Section.init()
     48             
     49             for index in 0..<subRange.count {
     50                 
     51                 var tmpSection = Section.init()
     52                 
     53                 if let countedProfit = subRange[index].countedProfit {
     54 
     55                     tmpProfit = countedProfit
     56                     
     57                     tmpSection.start = subRange[index].countedStart!
     58                     tmpSection.end = subRange[index].countedEnd!
     59                     tmpSection.hasProfit = subRange[index].countedHasProfit!
     60                     
     61                 } else {
     62                     if subRange[index].hasProfit {
     63                         
     64                         tmpProfit = -findMin(prices, subRange[index].start, subRange[index].end, &tmpSection)
     65 
     66                     } else {
     67                         
     68                         tmpProfit = findMax(prices, subRange[index].start, subRange[index].end, &tmpSection)
     69                     }
     70                     
     71                     
     72                     subRange[index].countedProfit = tmpProfit
     73                     subRange[index].countedStart = tmpSection.start
     74                     subRange[index].countedEnd = tmpSection.end
     75                     subRange[index].countedHasProfit = tmpSection.hasProfit
     76                 }
     77             
     78                 if maxProfit < tmpProfit {
     79                     
     80                     maxProfit = tmpProfit
     81                     maxIndex = index
     82 
     83                     maxSection = tmpSection
     84                 }
     85             }
     86 
     87             if maxIndex < 0 {
     88                 
     89                 break
     90             } else {
     91                 
     92                 let tmp = subRange[maxIndex]
     93                 
     94                 
     95                 maxSection.countedProfit = nil
     96                 maxSection.countedStart = nil
     97                 maxSection.countedEnd = nil
     98                 
     99                 if tmp.hasProfit {
    100                     
    101                     if maxSection.start > tmp.start {
    102                         subRange.append(Section.init(start: tmp.start, end:maxSection.start, hasProfit: true))
    103                     }
    104                     
    105                     if maxSection.end < tmp.end {
    106                         subRange.append(Section.init(start: maxSection.end, end: tmp.end, hasProfit: true))
    107                     }
    108 
    109                     maxSection.start += 1
    110                     maxSection.end -= 1
    111                     
    112                     if maxSection.start < maxSection.end {
    113                         subRange[maxIndex] = maxSection
    114                     } else {
    115                         subRange.remove(at: maxIndex)
    116                     }
    117                     
    118                     
    119                 } else {
    120                     
    121                     if tmp.start < maxSection.start - 1 {
    122                         subRange.append(Section.init(start: tmp.start, end: maxSection.start - 1, hasProfit: false))
    123                     }
    124                     
    125                     if maxSection.end + 1 < tmp.end {
    126                         subRange.append(Section.init(start: maxSection.end + 1, end: tmp.end, hasProfit: false))
    127                     }
    128                     
    129                     subRange[maxIndex] = maxSection
    130                     
    131                 }
    132                 
    133                 totalProfit += maxProfit
    134                 
    135             }
    136             
    137         }
    138         
    139         return totalProfit
    140     }
    141     
    142     func findMax(_ prices: [Int], _ startFlag: Int, _ endFlag: Int, _ section: inout Section) -> Int {
    143         
    144         if startFlag >= endFlag {
    145             return 0
    146         }
    147 
    148         section.hasProfit = true
    149         
    150         var tmpProfit = 0;
    151         var tmpStartIndex = startFlag;
    152         
    153         var total = 0
    154         
    155         for i in startFlag...endFlag {
    156             
    157             total = prices[i] - prices[tmpStartIndex]
    158             
    159             if total < 0 {
    160                 tmpStartIndex = i
    161                 total = 0
    162                 
    163             } else {
    164                 
    165                 if total > tmpProfit {
    166                     tmpProfit = total
    167                     section.end = i
    168                     section.start = tmpStartIndex
    169                 }
    170             }
    171         }
    172         
    173         return tmpProfit
    174     }
    175     
    176     func findMin(_ prices: [Int], _ startFlag: Int, _ endFlag: Int, _ section: inout Section) -> Int {
    177         
    178         if startFlag >= endFlag {
    179             return 0
    180         }
    181         
    182         
    183         section.hasProfit = false
    184         
    185         var tmpLoss = 0;
    186         var tmpStartIndex = startFlag;
    187         
    188         var total = 0
    189         
    190         for i in startFlag...endFlag {
    191             
    192             total = prices[i] - prices[tmpStartIndex]
    193             
    194             if total > 0 {
    195                 tmpStartIndex = i
    196                 total = 0
    197                 
    198             } else {
    199                 
    200                 if total < tmpLoss {
    201                     tmpLoss = total
    202                     section.end = i
    203                     section.start = tmpStartIndex
    204                 }
    205             }
    206         }
    207         
    208         return tmpLoss
    209     }
    210 }

    3464ms

      1 class Solution {
      2     
      3     class Section {
      4         
      5         var start: Int
      6         var end: Int
      7         var hasProfit: Bool
      8         
      9         
     10         init(start: Int, end: Int, hasProfit: Bool) {
     11             
     12             self.start = start
     13             self.end = end
     14             self.hasProfit = hasProfit
     15         }
     16     }
     17     
     18     func maxProfit(_ k: Int, _ prices: [Int]) -> Int {
     19         
     20         if prices.count < 2 {
     21             return 0
     22         }
     23         
     24         var totalProfit = 0
     25         
     26 
     27         var subRange:[Section] = []
     28         
     29         subRange.append(Section.init(start: 0, end: prices.count-1, hasProfit: false))
     30         
     31         for _ in 0..<k {
     32             
     33             
     34             var maxProfit = 0
     35             var tmpProfit = 0
     36             
     37             var maxSectionStart = 0
     38             var maxSectionEnd = 0
     39             
     40             var maxIndex = -1
     41             
     42             for index in 0..<subRange.count {
     43                 
     44                 var tmpReceive: (profit: Int, startIndex: Int, endIndex: Int)
     45            
     46                 
     47                 if subRange[index].hasProfit {
     48                     tmpReceive = findMin(prices, subRange[index].start, subRange[index].end)
     49                     tmpProfit = -tmpReceive.profit
     50                     
     51                 } else {
     52                     
     53                     tmpReceive = findMax(prices, subRange[index].start, subRange[index].end)
     54                     tmpProfit = tmpReceive.profit
     55                 }
     56                 
     57                 
     58                 if maxProfit < tmpProfit {
     59                     
     60                     maxProfit = tmpProfit
     61                     maxIndex = index
     62 
     63                     maxSectionStart = tmpReceive.startIndex
     64                     maxSectionEnd = tmpReceive.endIndex
     65 
     66                 }
     67             }
     68 
     69             if maxIndex < 0 {
     70                 
     71                 break
     72             } else {
     73                 
     74                 let tmp = subRange[maxIndex]
     75                 
     76             
     77                 if tmp.hasProfit {
     78                     
     79                     subRange.append(Section.init(start: tmp.start, end: maxSectionStart, hasProfit: true))
     80                     subRange.append(Section.init(start: maxSectionEnd, end: tmp.end, hasProfit: true))
     81                     
     82                     tmp.start = maxSectionStart + 1
     83                     tmp.end = maxSectionEnd - 1
     84                     tmp.hasProfit = false
     85 //                    subRange[maxIndex] = tmp
     86                     
     87                 } else {
     88                     
     89                     
     90                     subRange.append(Section.init(start: tmp.start, end: maxSectionStart - 1, hasProfit: false))
     91                     subRange.append(Section.init(start: maxSectionEnd + 1, end: tmp.end, hasProfit: false))
     92                     
     93                     tmp.start = maxSectionStart
     94                     tmp.end = maxSectionEnd
     95                     tmp.hasProfit = true
     96 //                    subRange[maxIndex] = tmp
     97                     
     98                 }
     99                 
    100                 totalProfit += maxProfit
    101                 
    102             }
    103             
    104         }
    105         
    106         return totalProfit
    107     }
    108     
    109     func findMax(_ prices: [Int], _ startFlag: Int, _ endFlag: Int) -> (profit: Int, startIndex: Int, endIndex: Int) {
    110         
    111         if startFlag >= endFlag {
    112             return (0, 0, 0)
    113         }
    114         
    115         var startIndex = 0
    116         var endIndex = 0
    117         
    118         var tmpProfit = 0;
    119         var tmpStartIndex = startFlag;
    120         
    121         var total = 0
    122         
    123         for i in startFlag...endFlag {
    124             
    125             total = prices[i] - prices[tmpStartIndex]
    126             
    127             if total < 0 {
    128                 tmpStartIndex = i
    129                 total = 0
    130                 
    131             } else {
    132                 
    133                 if total > tmpProfit {
    134                     tmpProfit = total
    135                     endIndex = i
    136                     startIndex = tmpStartIndex
    137                 }
    138             }
    139         }
    140         
    141         return (tmpProfit, startIndex, endIndex)
    142     }
    143     
    144     func findMin(_ prices: [Int], _ startFlag: Int, _ endFlag: Int) -> (profit: Int, startIndex: Int, endIndex: Int) {
    145         
    146         if startFlag >= endFlag {
    147             return (0, 0, 0)
    148         }
    149         
    150         var startIndex = 0
    151         var endIndex = 0
    152         
    153         var tmpLoss = 0;
    154         var tmpStartIndex = startFlag;
    155         
    156         var total = 0
    157         
    158         for i in startFlag...endFlag {
    159             
    160             total = prices[i] - prices[tmpStartIndex]
    161             
    162             if total > 0 {
    163                 tmpStartIndex = i
    164                 total = 0
    165                 
    166             } else {
    167                 
    168                 if total < tmpLoss {
    169                     tmpLoss = total
    170                     endIndex = i
    171                     startIndex = tmpStartIndex
    172                 }
    173             }
    174         }
    175         
    176         return (tmpLoss, startIndex, endIndex)
    177     }
    178 }
  • 相关阅读:
    禁用网络连接后无法访问本机数据库的问题
    DevExpress使用笔记
    DEV控件 皮肤问题
    SQLServer2008导入Excel遇到的问题
    InnoSetup使用笔记
    SQLServer清空数据库中所有表的数据
    MS SQL Server2000转换成MySQL
    由MySQL登录不了引发的一些问题
    onerror事件
    DIV+CSS一些小小的技巧
  • 原文地址:https://www.cnblogs.com/strengthen/p/10179523.html
Copyright © 2011-2022 走看看