I solving the problem of "Best-time-to-buy-and-sell-stock" at leetcode https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/ with 2 approaches:
With first, I transformed Array to List and handle list recursively:
def maxProfit(prices: Array[Int]): Int = { @tailrec def maxProfitHelp(prices: List[Int], maxProfit: Int, lastBuy: Int): Int = { prices match { case Nil => maxProfit case head :: tail => if (head > lastBuy) { maxProfitHelp(tail, Math.max(maxProfit, head - lastBuy), lastBuy) } else { maxProfitHelp(tail, maxProfit, head) } } } val listPrices = prices.toList maxProfitHelp(listPrices.tail, 0, listPrices.head) }
This gave time performance 962 ms. (Memory: 71,70 MB)
With second I tried to handle original array in the same recursive manned.
def maxProfitWithoutList(prices: Array[Int]): Int = { @tailrec def maxProfitHelp(prices: Array[Int], maxProfit: Int, lastBuy: Int): Int = { prices match { case c if c.isEmpty => maxProfit case c => if (c.head > lastBuy) { maxProfitHelp(c.tail, Math.max(maxProfit, c.head - lastBuy), lastBuy) } else { maxProfitHelp(c.tail, maxProfit, c.head) } } } maxProfitHelp(prices.tail, 0, prices.head) }
And time performance is 9134 ms. (Memory: 75,47 MB)
So with Array-recursion complexity is 10 times worse (!) as with List-recursion!
Why did this happen?
Arraycopies all the memory. Don't useArraysas a newcomer, they have a lot of problems, one of them being terrible at performance if you don't use them appropriately.