1956. Minimum Time For K Virus Variants to Spread


Problem Explanation

This problem presents us with a uniquely challenging task. There are n unique virus variants spread across an infinite 2D grid. Each virus variant is represented as a set of point coordinates (x, y) at day 0. Each day, every cell infected with a virus variant spreads the virus to all the neighbouring cells in four cardinal directions: up, down, left, and right. It's important to note that if a cell has multiple virus variants, all of them spread without interfering each other.

Our task is to find the minimum integer number of days it would take for any point to contain at least 'k' unique virus variants.

For instance, if we have points [[1,1],[2,2],[3,3]] and k = 3, the function should return 3. This is because on day 1, virus 1 will be at points (1,1),(2,2) and (3,3). On day 2, they will have spread reaching (3,3) and virus 2 and 3 also reaching (3,3) approximately on day 3.

Solution Explanation

The solution uses an algorithm that iteration through possible points within a set upper limit (kMax), for each of these points, it measures and keeps the k smallest Manhattan distances from the virus points to this point (a,b). It then keeps track of the minimum of these k smallest distances.

The Manhattan distance between two points are calculated as abs(x1 - x2) + abs(y1 - y2) where (x1, y1) and (x2, y2) are the coordinates for the two points.

Algorithm Steps

  1. Set a value of kMax = 100, and a maximum value 'ans' (to record our minimum distance)

  2. Now for each point (a, b) from (1, 1) to (kMax, kMax), do the following:

    a. For each virus variant point, calculate its distance from (a, b) and add it to a maximum heap.

    b. If the heap's size becomes more than k, we remove the maximum distance from it (it is of no use to us anymore)

    c. After checking all points, we compare the maximum value in the heap (which is the kth smallest distance) with our current 'ans'. Update 'ans' if this value is smaller.

  3. Return 'ans' as this minima would give us the minimum days for a point to contain atleast k variants.

Python Solution

1
2python
3import heapq
4
5class Solution:
6    
7    def minDayskVariants(self, points, k):
8        kMax = 100
9        ans = float('inf')
10        
11        for a in range(1, kMax+1):
12            for b in range(1, kMax+1):
13                
14                # Priority queue to store K smallest distances
15                maxHeap = []
16
17                for point in points:
18                    # calculate and push the manhattan distances into heap
19                    distance = abs(point[0] - a) + abs(point[1] - b)
20                    heapq.heappush(maxHeap, -distance)
21
22                    # if size > k, pop the maximum 
23                    if len(maxHeap) > k:
24                        heapq.heappop(maxHeap)
25                        
26                # update our minimum 
27                ans = min(ans, -maxHeap[0])
28        return ans

Here, we make use of python's heapq module to implement heap operations. For Java, JavaScript, C#, and C++ solutions, we can follow similar approach while suitably using each languages' heap features. It is worth noting that use heap for this problem because we want to efficiently get the k smallest distances. We convert the distances into negative while pushing into the heap. This way, the maximum distance, which we want to pop off, always stays at the top of the heap. This is because heapq in python only supports min heap.# JavaScript Solution

In JavaScript, there's no built-in heap data structure. However, we can use an array to emulate it.

1
2javascript
3class Solution {
4    constructor() {
5        this.kMax = 100;
6    }
7
8    minDayskVariants(points, k) {
9        let ans = Infinity;
10
11        for (let a = 1; a < this.kMax+1; a++) {
12            for (let b = 1; b < this.kMax+1; b++) {
13                let maxHeap = [];
14
15                for (let point of points) {
16                    let distance = Math.abs(point[0] - a) + Math.abs(point[1] - b);
17                    this.pushToHeap(maxHeap, -distance);
18                    if (maxHeap.length > k) {
19                        this.popFromHeap(maxHeap);
20                    }
21                }
22                ans = Math.min(ans, -maxHeap[0]);
23            }
24        }
25        return ans;
26    }
27
28    pushToHeap(heap, val) {
29        heap.push(val);
30        heap.sort((a, b) => b - a);
31    }
32
33    popFromHeap(heap) {
34        heap.shift();
35    }
36}

The pushToHeap method sorts the heap in descending order every time an element is pushed. popFromHeap method removes the largest element (located in the 0 index due to sorting) from the heap.

Java Solution

Java provides a PriorityQueue class that we can use as a max heap.

1
2java
3public class Solution {
4
5    private static final int KMAX = 100;
6    
7    public int minDayskVariants(int[][] points, int k) {
8        
9        int ans = Integer.MAX_VALUE;
10        for (int a = 1; a < KMAX+1; a++) {
11            for (int b = 1; b < KMAX+1; b++) {
12                
13                // Max heap to store K smallest distances
14                PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
15
16                for (int[] point : points) {
17                    int distance = Math.abs(point[0] - a) + Math.abs(point[1] - b);
18                    maxHeap.add(-distance);
19                    if (maxHeap.size() > k) {
20                        maxHeap.poll();
21                    }
22                }
23                ans = Math.min(ans, -maxHeap.peek());
24            }
25        }
26        return ans;
27    }
28}

Here, Comparator.reverseOrder() is used to create a max heap by reversing the natural order. Similar to the previous solutions, we push negative distances to the heap.

In conclusion, all the three solutions are implementing the same logic but in different ways as per the language’s features. This can help to understand how we can translate solutions between different languages.

Not Sure What to Study? Take the 2-min Quiz to Find Your Missing Piece:

Breadth first search can be used to find the shortest path between two nodes in a directed graph.

Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:

Depth first search is equivalent to which of the tree traversal order?

Solution Implementation

Not Sure What to Study? Take the 2-min Quiz:

Which of the following uses divide and conquer strategy?

Fast Track Your Learning with Our Quick Skills Quiz:

What is the best way of checking if an element exists in a sorted array once in terms of time complexity? Select the best that applies.


Recommended Readings


Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.


TA 👨‍🏫