Minimum time to pick all elements with a cooldown period
Last Updated :
01 Aug, 2023
Given an array arr[] of size n, where each element in the array represents a value between 1 and n. Additionally, you are given another array time[], where time[i] (1 ≤ i ≤ n) represents the minimum time required before you can pick the ith element again after you have already picked it, the task is to determine the minimum amount of time required to pick all the elements of the arr[] array from left to right, subject to the following condition: once you have picked an element, you must wait for time[element] seconds before you can pick it again. You can move from one index i to another index i+1 in one second, and there is no additional time required to pick an element. Follow 1- based indexing, meaning the first element is at index 1.
Examples:
Input: n = 4, arr[] = {1, 2, 3, 3}, time[]= {1, 2, 3, 4}
Output: 5
Explanation:
- You start from index 1, and pick arr[1] i.e. 1 in no time.
- In 1 sec you move from index 1 to 2, and pick arr[2] i.e. 2, total time = 1.
- In next 1 sec you move from index 2 to 3, and pick arr[3] i.e. 3, total time = 2.
- In next 1 sec you move from index 3 to 4, and arr[4] is 3, which you have taken already at time 2, hence you need to wait for time[arr[i]] sec to again pick arr[i], time[arr[i]] = time[3] = 3, hence in 1 sec you moved from index 3 to 4, and waited for next 2 sec, and finally picked arr[4], total time = 5.
Input: n = 4, arr[] = {1, 2, 3, 4}, time[] = {1, 2, 3, 4}
Output: 3
Explanation: All the array elements are different hence, you do not have to wait for any arr[i] before picking it, hence the total time will be 3, which is the time required to traverse the array.
Approach: To solve the problem follow the below steps:
- Declare a HashMap<Integer, Integer> to keep a track of the element that already came along with its previous time.
- Declare a cache array to store the time of individual elements when they can be picked.
- Traverse through the array and if the element is not present in the map in the form of a key, we add the element and the previous time from cache array +1 in the map.
- Else if it is present, we calculate the waiting time, the element has to wait before its time is updated and we store that waited time in a variable and check with the time array, if it has achieved the stimulated time, we update it in the cache array.
- Return the value of cache[n-1].
Below is the code for the above approach:
C++
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
int totalTime( int n, int arr[], int time [])
{
map< int , int > hm;
vector< long long > cache(n);
hm[arr[0]] = 0;
cache[0] = 0;
for ( int i = 1; i < n; i++) {
if (hm.count(arr[i])) {
long long currentTime = cache[i - 1] + 1;
long long previousTime = cache[hm[arr[i]]];
long long waited = currentTime - previousTime;
if (waited < time [arr[i] - 1]) {
currentTime += time [arr[i] - 1] - waited;
}
cache[i] = currentTime;
hm[arr[i]] = i;
}
else {
hm[arr[i]] = i;
cache[i] = cache[i - 1] + 1;
}
}
return cache[n - 1];
}
int main()
{
int n = 4;
int arr[] = { 1, 2, 3, 3 };
int time [] = { 1, 2, 3, 4 };
cout << totalTime(n, arr, time );
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static long totalTime( int n, int arr[],
int time[])
{
HashMap<Integer, Integer> hm = new HashMap<>();
long cache[] = new long [n];
hm.put(arr[ 0 ], 0 );
cache[ 0 ] = 0 ;
for ( int i = 1 ; i < n; i++) {
if (hm.containsKey(arr[i])) {
long currentTime = cache[i - 1 ] + 1 ;
long previousTime = cache[hm.get(arr[i])];
long waited = currentTime - previousTime;
if (waited < time[arr[i] - 1 ]) {
currentTime
+= time[arr[i] - 1 ] - waited;
}
cache[i] = currentTime;
hm.put(arr[i], i);
}
else {
hm.put(arr[i], i);
cache[i] = cache[i - 1 ] + 1 ;
}
}
return cache[n - 1 ];
}
public static void main(String[] args)
{
int n = 4 ;
int arr[] = { 1 , 2 , 3 , 3 };
int time[] = { 1 , 2 , 3 , 4 };
System.out.println(totalTime(n, arr, time));
}
}
|
Python3
def totalTime(n, arr, time):
hm = {}
cache = [ 0 ] * n
hm[arr[ 0 ]] = 0
cache[ 0 ] = 0
for i in range ( 1 , n):
if arr[i] in hm:
current_time = cache[i - 1 ] + 1
previous_time = cache[hm[arr[i]]]
waited = current_time - previous_time
if waited < time[arr[i] - 1 ]:
current_time + = time[arr[i] - 1 ] - waited
cache[i] = current_time
hm[arr[i]] = i
else :
hm[arr[i]] = i
cache[i] = cache[i - 1 ] + 1
return cache[n - 1 ]
if __name__ = = "__main__" :
n = 4
arr = [ 1 , 2 , 3 , 3 ]
time = [ 1 , 2 , 3 , 4 ]
print (totalTime(n, arr, time))
|
C#
using System;
using System.Collections.Generic;
class Program {
public static long totalTime( int n, int [] arr,
int [] time)
{
Dictionary< int , int > hm
= new Dictionary< int , int >();
long [] cache = new long [n];
hm.Add(arr[0], 0);
cache[0] = 0;
for ( int i = 1; i < n; i++) {
if (hm.ContainsKey(arr[i])) {
long currentTime = cache[i - 1] + 1;
long previousTime = cache[hm[arr[i]]];
long waited = currentTime - previousTime;
if (waited < time[arr[i] - 1]) {
currentTime
+= time[arr[i] - 1] - waited;
}
cache[i] = currentTime;
hm[arr[i]] = i;
}
else {
hm.Add(arr[i], i);
cache[i] = cache[i - 1] + 1;
}
}
return cache[n - 1];
}
static void Main( string [] args)
{
int n = 4;
int [] arr = { 1, 2, 3, 3 };
int [] time = { 1, 2, 3, 4 };
Console.WriteLine(totalTime(n, arr, time));
}
}
|
Javascript
function totalTime(n, arr, time) {
const hm = new Map();
const cache = new Array(n).fill(0);
hm.set(arr[0], 0);
cache[0] = 0;
for (let i = 1; i < n; i++) {
if (hm.has(arr[i])) {
let currentTime = cache[i - 1] + 1;
let previousTime = cache[hm.get(arr[i])];
let waited = currentTime - previousTime;
if (waited < time[arr[i] - 1]) {
currentTime += time[arr[i] - 1] - waited;
}
cache[i] = currentTime;
hm.set(arr[i], i);
} else {
hm.set(arr[i], i);
cache[i] = cache[i - 1] + 1;
}
}
return cache[n - 1];
}
const n = 4;
const arr = [1, 2, 3, 3];
const time = [1, 2, 3, 4];
console.log(totalTime(n, arr, time));
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...