To implement this solution, we can calculate the prefix sum for each index in the input array and use a hash table to store it. Then, we traverse the array and use the hash table to find the shortest subarrays with a sum equal to k.
The complete algorithm is given below:
First, we will traverse through the input array once and store the key-value pairs in a hash table such that, for every ith index, the key is the sum of hoursPerDay[0] to hoursPerDay[i] and the value is i.
We will also add (0, -1) to the hash table as the default.
Now, we will traverse through the array again, and for every i, we will find the minimum value of the length of the subarray on the left or starting with i, whose value is equal to k.
Then, we will find another subarray starting with i + 1, whose sum is k.
We will update the result with the minimum value of the sum of both the subarrays. This is possible because all the values are positive, and the value of the sum is strictly increasing.
xxxxxxxxxx
import scala.collection.mutable.HashMap
object Main {
def twoSetsOfDays(hoursPerDay: Array[Int], k: Int): Int = {
var hmap = HashMap[Int, Int]()
var sum = 0
var lsize = Integer.MAX_VALUE
var result = Integer.MAX_VALUE
hmap.put(0,-1)
for (i <- 0 until hoursPerDay.length) {
sum += hoursPerDay(i)
hmap.put(sum,i)
}
sum = 0
for (i <- 0 until hoursPerDay.length) {
sum += hoursPerDay(i)
if (hmap.contains(sum - k)) { // stores minimum length of sub-array ending with index<= i with sum k. This ensures non- overlapping property.
lsize = Math.min(lsize, i - hmap(sum - k))
}
//searches for any sub-array starting with index i+1 with sum k.
if (hmap.contains(sum + k) && lsize < Integer.MAX_VALUE)
result = Math.min(result, hmap(sum + k) - i + lsize)
}
if (result == Integer.MAX_VALUE) -1
else result
}
def main(args: Array[String]): Unit = {
val hoursPerDay = Array(1, 2, 2, 3, 2, 6, 7, 2, 1, 4, 8)
val k = 5
println(twoSetsOfDays(hoursPerDay, k))
}
}