"Maximum Fruits Harvested After at Most K Steps" accepted solution improved by parallel execution
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user