
Problem Statement
In the given problem, we have an array named colors
which contains elements representing three colors identified by integers 1
, 2
, and 3
. Alongside, a list of queries is provided where each query is characterized by two integers: i
which represents an index in the colors array, and c
which represents a target color. The task is to find out the shortest distance from the specified index i
to any location in the colors
array where the element matches the target color c
. If no such element exists, the answer should be -1
. The challenge lies in efficiently finding the shortest distance for potentially large arrays and numerous queries.
Examples
Example 1
Input:
colors = [1,1,2,1,3,2,2,3,3], queries = [[1,3],[2,2],[6,1]]
Output:
[3,0,3]
Explanation:
The nearest 3 from index 1 is at index 4 (3 steps away). The nearest 2 from index 2 is at index 2 itself (0 steps away). The nearest 1 from index 6 is at index 3 (3 steps away).
Example 2
Input:
colors = [1,2], queries = [[0,3]]
Output:
[-1]
Explanation:
There is no 3 in the array.
Constraints
1 <= colors.length <= 5 * 10⁴
1 <= colors[i] <= 3
1 <= queries.length <= 5 * 10⁴
queries[i].length == 2
0 <= queries[i][0] < colors.length
1 <= queries[i][1] <= 3
Approach and Intuition
Based on both the examples and constraints provided, we can derive an effective strategy to address the problem:
Given that each query requires determining the smallest distance from a specific index to any index with a given color, a brute-force approach where each query leads to a full scan of the array could be inefficient. Instead, preprocessing the array to map the positions of each color can speed up query responses.
Create a data structure to keep track of the indices in the
colors
array where each color appears. For example, use a dictionarycolor_positions
with keys as the distinct colors (1
,2
,3
) and values as lists of indices where these colors appear in sorted order.For every query:
- Retrieve the list of valid indices for the target color
c
. - If no such indices exist, the result for this query is
-1
. - If indices exist, use efficient search methods (like binary search) to find the closest index to
i
. Compare the distances to the nearest lower and higher (or exact match) indices to determine the minimal distance.
- Retrieve the list of valid indices for the target color
Consider edge cases such as:
- The queried index is at the start or the end of the array.
- The color does not exist anywhere in the array.
- Multiple queries asking for the same color from the same index.
Balance between preprocessing time and query answer time given the constraints on array and query sizes, ensuring that our approach efficiently handles up to the upper limit of these constraints.
Solutions
- Java
class Solution {
public List<Integer> findNearestColors(int[] palette, int[][] requests) {
int len = palette.length;
int[] farRight = {0, 0, 0};
int[] farLeft = {len - 1, len - 1, len - 1};
int[][] proximity = new int[3][len];
for (int i = 0; i < 3; i++) {
Arrays.fill(proximity[i], -1);
}
// Forward traversal
for (int i = 0; i < len; i++) {
int c = palette[i] - 1;
for (int j = farRight[c]; j < i + 1; j++) {
proximity[c][j] = i - j;
}
farRight[c] = i + 1;
}
// Backward traversal
for (int i = len - 1; i >= 0; i--) {
int c = palette[i] - 1;
for (int j = farLeft[c]; j > i - 1; j--) {
if (proximity[c][j] == -1 || proximity[c][j] > j - i) {
proximity[c][j] = j - i;
}
}
farLeft[c] = i - 1;
}
List<Integer> response = new ArrayList<>();
for (int[] req : requests) {
response.add(proximity[req[1] - 1][req[0]]);
}
return response;
}
}
This Java solution involves finding the shortest distance for each request from the given palette to the target colors. The Solution
class contains a method findNearestColors
that processes the input palette of colors and a series of requests, each specifying a position and a target color. Follow these steps to understand this code:
Initialize necessary variables:
len
- the length of the palette array.farRight
andfarLeft
- arrays that keep track of the rightmost and leftmost indices reached by each color in the palette.proximity
- a 2D-array where each row corresponds to a color and each column corresponds to the shortest distance of the respective color from a certain index.
Fill the proximity matrix with initial values of
-1
, a placeholder indicating no proximity calculated yet.Conduct a forward traversal over the palette:
- Update the
farRight
array whenever a new instance of a color is found. - Fill in distances for each color index range swept from the previous position to the current.
- Update the
Conduct a backward traversal:
- Similar to the forward pass, update the
farLeft
. - Compare and possibly update proximity values, ensuring they hold the minimum distance for backward encounters of the same color.
- Similar to the forward pass, update the
Construct the response list:
- For each request defined by the start index and a target color from the
requests
array, retrieve the shortest distance from theproximity
array and add it to the response list.
- For each request defined by the start index and a target color from the
Return the list of shortest distances.
By using two sweeps across the palette, the solution efficiently calculates both forward and backward closest distances for each color, ensuring that the final response values represent the closest possible distances to the requested colors from specified positions.
- Python
class Solution:
def minimumDistancePerColor(self, colorList: List[int], searchQueries: List[List[int]]) -> List[int]:
# Establish basic parameters and structure
color_count = len(colorList)
nearest_right = [0, 0, 0]
nearest_left = [color_count - 1, color_count - 1, color_count - 1]
color_distance = [[-1] * color_count for _ in range(3)]
# Populate distances from right to left
for index in range(color_count):
current_color = colorList[index] - 1
for position in range(nearest_right[current_color], index + 1):
color_distance[current_color][position] = index - position
nearest_right[current_color] = index + 1
# Populate distances from left to right
for index in range(color_count - 1, -1, -1):
current_color = colorList[index] - 1
for position in range(nearest_left[current_color], index - 1, -1):
# Update if no distance found yet or a closer distance is found
if color_distance[current_color][position] == -1 or color_distance[current_color][position] > position - index:
color_distance[current_color][position] = position - index
nearest_left[current_color] = index - 1
return [color_distance[color - 1][position] for position, color in searchQueries]
The given Python code is designed to find the shortest distance to a target color in a list based on multiple queries. This capability is encapsulated within a class named Solution
that features the method minimumDistancePerColor
which accepts colorList
, a list of integers representing colors, and searchQueries
, a list of lists detailing position and target color queries.
The method workflow is as follows:
Initialize variables
color_count
to get the number of elements incolorList
, andnearest_right
andnearest_left
to serve as arrays to track the nearest rightmost and leftmost indices of each color.Set up a 2D list
color_distance
where each sublist represents distances for a specific color from every position to the nearest occurrence of that color to the left and right.Populate the
color_distance
array with distances from the rightmost index ofcolorList
to the left. This is achieved by iterating from the start to the end ofcolorList
. For each color, calculate the distance from the previous indexed position to the current position being evaluated.Populate the
color_distance
array with distances from the leftmost index ofcolorList
to the right. This operates by iterating from the end to the start ofcolorList
, updating distances only if no previous distance is found or a shorter distance is identified.For each query in
searchQueries
, extract the relevant distance using thecolor_distance
array filled previously enabling each position and desired color to efficiently fetch the computed nearest distance.
This approach in combining forward and backward passes to compute distances ensures each query result retrieval in constant time, effective for scenarios where multiple queries on large datasets are expected.
No comments yet.