"Maximum Fruits Harvested After at Most K Steps" accepted solution improved by parallel execution

This commit is contained in:
2022-06-06 22:53:55 +03:00
parent e3193bd1bb
commit e7075b017a

View File

@@ -1,5 +1,96 @@
package main
import "sync"
func fromRightToLeft(fruityPrefix []int, startPos int, k int, leftLimit int, rightLimit int, pwg *sync.WaitGroup, presult *int) {
calcFruitySliceSum := func(begin int, end int) int {
begin--
if begin < 0 {
return fruityPrefix[end]
}
return fruityPrefix[end] - fruityPrefix[begin]
}
windowSize := k / 2
maxFruits := calcFruitySliceSum(startPos, rightLimit)
delta := k - windowSize*2
windowBegin :=
startPos - delta // in case number of steps cannot be fully divided by 2, start position is shifted 1 position to the left
windowEnd :=
windowBegin + windowSize + delta // for odd numbers of k we need to adjust wnd sz +1
if windowEnd > rightLimit {
windowBegin -= 2 * (windowEnd - rightLimit)
windowEnd = rightLimit
windowSize = windowEnd - windowBegin - delta
}
endCycle := false
for !endCycle {
if windowBegin <= leftLimit {
windowBegin = leftLimit
endCycle = true
}
localMaxFruits := calcFruitySliceSum(windowBegin, windowEnd)
if localMaxFruits > maxFruits {
maxFruits = localMaxFruits
}
windowSize++
windowEnd--
windowBegin = windowEnd - windowSize - delta
}
*presult = maxFruits
pwg.Done()
}
func fromLeftToRight(fruityPrefix []int, startPos int, k int, leftLimit int, rightLimit int) int {
calcFruitySliceSum := func(begin int, end int) int {
begin--
if begin < 0 {
return fruityPrefix[end]
}
return fruityPrefix[end] - fruityPrefix[begin]
}
maxFruits := calcFruitySliceSum(leftLimit, startPos)
windowSize := k / 2
delta := k - windowSize*2
windowEnd := startPos + delta
windowBegin := windowEnd - windowSize - delta
if windowBegin < leftLimit {
windowEnd += 2 * (leftLimit - windowBegin)
windowBegin = leftLimit
windowSize = windowEnd - delta - windowBegin
}
endCycle := false
for !endCycle {
if windowEnd >= rightLimit {
windowEnd = rightLimit
endCycle = true
}
localMaxFruits := calcFruitySliceSum(windowBegin, windowEnd)
if localMaxFruits > maxFruits {
maxFruits = localMaxFruits
}
windowSize++
windowBegin++
windowEnd = windowBegin + windowSize + delta
}
return maxFruits
}
func MaxTotalFruits(fruits [][]int, startPos int, k int) int {
if len(fruits) == 0 || k < 0 {
return 0
@@ -46,79 +137,19 @@ func MaxTotalFruits(fruits [][]int, startPos int, k int) int {
}
//fmt.Println("rightLimit = ", rightLimit)
windowSize := k / 2
maxFruits := 0
calcFruitySliceSum := func(begin int, end int) int {
begin--
if begin < 0 {
return fruityPrefix[end]
}
wg := new(sync.WaitGroup)
wg.Add(1)
return fruityPrefix[end] - fruityPrefix[begin]
go fromRightToLeft(fruityPrefix, startPos, k, leftLimit, rightLimit, wg, &maxFruits)
alternativeMaxFruits := fromLeftToRight(fruityPrefix, startPos, k, leftLimit, rightLimit)
wg.Wait()
if maxFruits > alternativeMaxFruits {
return maxFruits
}
maxFruits := calcFruitySliceSum(startPos, rightLimit)
delta := k - windowSize*2
windowBegin :=
startPos - delta // in case number of steps cannot be fully divided by 2, start position is shifted 1 position to the left
windowEnd :=
windowBegin + windowSize + (k - windowSize*2) // for odd numbers of k we need to adjust wnd sz +1
if windowEnd > rightLimit {
windowBegin -= 2 * (windowEnd - rightLimit)
windowEnd = rightLimit
windowSize = windowEnd - windowBegin - (k - windowSize*2)
}
endCycle := false
for !endCycle {
if windowBegin <= leftLimit {
windowBegin = leftLimit
endCycle = true
}
localMaxFruits := calcFruitySliceSum(windowBegin, windowEnd)
if localMaxFruits > maxFruits {
maxFruits = localMaxFruits
}
windowSize++
windowEnd--
windowBegin = windowEnd - windowSize - delta
}
alternativeMaxFruits := calcFruitySliceSum(leftLimit, startPos)
if alternativeMaxFruits > maxFruits {
maxFruits = alternativeMaxFruits
}
windowSize = k / 2
windowEnd = startPos + (k - windowSize*2)
windowBegin = windowEnd - windowSize - (k - windowSize*2)
if windowBegin < leftLimit {
windowEnd += 2 * (leftLimit - windowBegin)
windowBegin = leftLimit
windowSize = windowEnd - (k - windowSize*2) - windowBegin
}
endCycle = false
for !endCycle {
if windowEnd >= rightLimit {
windowEnd = rightLimit
endCycle = true
}
localMaxFruits := calcFruitySliceSum(windowBegin, windowEnd)
if localMaxFruits > maxFruits {
maxFruits = localMaxFruits
}
windowSize++
windowBegin++
windowEnd = windowBegin + windowSize + delta
}
return maxFruits
return alternativeMaxFruits
}