-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathBestTimeStockII.kt
62 lines (56 loc) · 2.46 KB
/
BestTimeStockII.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package questions
import _utils.UseCommentAsDocumentation
import utils.shouldBe
import java.util.*
/**
* You are given an integer array prices where `prices[i]` is the price of a given stock on the ith day.
* On each day, you may decide to buy and/or sell the stock.
* You can only hold at most one share of the stock at any time.
* However, you can buy it then immediately sell it on the same day.
* Find and return the maximum profit you can achieve.
*
* [Source](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/)
*
* @see [BestTimeStock]
*/
@UseCommentAsDocumentation
private object BestTimeStockII
private fun maxProfit(prices: IntArray): Int {
val futureSellPrices = Array<Int>(prices.size) { Integer.MIN_VALUE }
val futureBuyPrices = Array<Int>(prices.size) { Integer.MAX_VALUE }
for (index in prices.lastIndex downTo 0) {
futureSellPrices[index] = maxOf(futureSellPrices.getOrNull(index + 1) ?: Integer.MIN_VALUE, prices[index])
futureBuyPrices[index] = minOf(futureBuyPrices.getOrNull(index + 1) ?: Integer.MAX_VALUE, prices[index])
}
var result = 0
var boughtAt: Int? = null
for (index in 0..prices.lastIndex) {
val maxSell = futureSellPrices[index] // max sell price in future
val minBuy = futureBuyPrices[index] // min buy price in future
val current = prices[index]
if (boughtAt == null) { // haven't bought yet
if (current == maxSell) { // if this is maxSell price, then don't buy
boughtAt = null
} else if (current in minBuy until maxSell) { // buy if you can sell it at higher price in future
boughtAt = current
}
} else { // if already bought, see if you can sell
if (current == maxSell) { // this is max sell price, then sell it!
result += (current - boughtAt) // sold
} else if (current > boughtAt && current in minBuy until maxSell) { // sell if there's profit
result += (current - boughtAt) //sold
}
if (current in minBuy until maxSell) { // re-buy it if you can have profit in the future
boughtAt = current // re-bought at the same day
} else {
boughtAt = null // sold
}
}
}
return result
}
fun main() {
maxProfit(intArrayOf(7, 1, 5, 3, 6, 4)) shouldBe 7
maxProfit(intArrayOf(2, 4, 1)) shouldBe 2
maxProfit(intArrayOf(1, 2, 3, 4, 5)) shouldBe 4
}