2078. Two Furthest Houses With Different Colors
Problem Description
The problem provides a street lined with n
evenly spaced houses, each with a color represented numerically. An array colors
is given, where colors[i]
depicts the color of the i-th
house. The task is to determine the maximum distance between any two houses that have different colors.
This distance is measured in terms of the array indices, thus the distance between the i-th
and j-th
houses is abs(i - j)
, which is the absolute value of the difference between their indices.
The key to this problem is identifying the farthest pair of houses with dissimilar colors, which will give us the largest possible index difference.
Intuition
The solution utilizes the fact that to maximize the distance between two differently colored houses, we should consider houses at the ends of the street.
-
First, we check if the first and last houses (
colors[0]
andcolors[-1]
) are different. If they are, this is the maximum possible distance (n - 1
) and we can return this value immediately. -
If the colors of the first and last house are the same, we then need to check for the next closest house to each of them that has a different color to calculate the maximum distance.
-
We initialize two pointers,
i
from the start (excluding the first house) andj
from the end (excluding the last house), and move each pointer towards the center of the array until a house with a different color is found. -
While
colors[i]
is the same as the first house's color, we incrementi
. Similarly, we decrementj
whilecolors[j]
is the same as the first house's color. This process skips over houses with the same color as the first house. -
After finding the differently colored houses, we calculate the distance from them to the opposite ends of the street, specifically
n - i - 1
andj
. -
The maximum distance is the larger of these two values, ensuring we have the greatest possible range between two houses of different colors, as required.
This approach ensures we find the optimal distance without checking every possible pair, which would be less efficient for large arrays.
Learn more about Greedy patterns.
Solution Approach
The implementation of the solution leverages a straightforward approach without the use of complex algorithms or data structures. Instead, it utilizes a simple iterative process with two pointers and basic conditional logic.
-
Firstly, the length of the
colors
list,n
, is obtained. -
The colors of the first (
colors[0]
) and last (colors[-1]
) houses are compared. If they are different, the solution is immediately found because the maximum distance in a linear array is between the endpoints (indexes0
andn - 1
). Thus, the code returnsn - 1
.if colors[0] != colors[-1]: return n - 1
-
If the colors are the same, two pointers
i
andj
are introduced. The pointeri
is initialized to start from the second house (index 1
) and moves towards the end of the street, whilej
is initialized to start from the second to last house (index n - 2
) and moves towards the beginning of the street.i, j = 1, n - 2
-
The while loops are used to advance
i
andj
. As long ascolors[i]
matches the color of the first house,i
is incremented. And as long ascolors[j]
matches the color of the first house,j
is decremented. These loops stop at the first occurrences of colors different from the first house's color.while colors[i] == colors[0]: i += 1 while colors[j] == colors[0]: j -= 1
-
After exiting the loops,
i
is at the position of the first house from the left with a different color than the first house, andj
is at the position of the first house from the right with a different color than the first house. The distances from these points to the respective ends of the street are calculated:return max(n - i - 1, j)
The function returns the greater of these two distances. The subtraction of
1
inn - i - 1
accounts for the zero-based indexing. By taking the maximum of these two distances, we ensure that we are indeed returning the maximum possible distance between two houses with different colors.
This solution approach does not require sorting or searching algorithms, nor any particular data structure other than the array itself. It efficiently traverses the array at most twice, resulting in a time complexity of O(n). This efficient method bypasses the need to compare every pair of houses, thereby preventing the solution from becoming inefficient, especially for large arrays.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's consider a small example where the colors
array has 7 houses with the following colors represented by the numbers: 1 1 1 4 5 1 1
. The length of this array, n
, is 7.
-
We start by comparing the
colors[0]
, which is 1 (the color of the first house), withcolors[-1]
, which is also 1 (the color of the seventh house). Since these colors are the same, we cannot conclude at this point and need to examine further. -
Set up two pointers:
- Pointer
i
starts from index 1 (the second house). - Pointer
j
starts from index 5 (the second to last house, orn - 2
).
- Pointer
-
Conduct a while loop to move
i
towards the right until a house with a different color is found.- Loop continues until
colors[i]
differs fromcolors[0]
. The while loop would iterate as follows:colors[1]
is 1, same as first house, incrementi
(nowi
is 2).colors[2]
is 1, still the same, incrementi
(nowi
is 3).colors[3]
is 4, which is different! Stop here.
- Loop continues until
-
Conduct another while loop to move
j
towards the left until a house with a different color is found (relative to the color of the first house).- Loop continues until
colors[j]
differs fromcolors[0]
. The while loop would iterate as follows:colors[5]
is 1, same as the first house, decrementj
(nowj
is 4).colors[4]
is 5, which is different! Stop here.
- Loop continues until
-
After the loops, we have
i
at index 3 andj
at index 4. Now we calculate the distances from these houses to the ends of the street:- Distance from the house at
i
to the end of the street:n - i - 1
→7 - 3 - 1
= 3 - Distance from the house at
j
to the beginning of the street:j
→ 4
- Distance from the house at
-
The maximum of the two distances is 4, which occurs between the house with color 5 (at index 4) and the first house (at index 0).
The final answer is the maximum distance of 4, which is the maximum distance between any two houses with different colors in the given colors
array.
Solution Implementation
1from typing import List
2
3class Solution:
4 def maxDistance(self, colors: List[int]) -> int:
5 # Get the number of elements in the 'colors' list
6 num_colors = len(colors)
7
8 # If the first and last colors are different, the maximum distance is the length of the list minus one
9 if colors[0] != colors[-1]:
10 return num_colors - 1
11
12 # Initialize two pointers, one starting from the beginning and the other from the end of the list
13 # These pointers will be used to find the maximum distance on both ends of the list
14 left_index, right_index = 1, num_colors - 2
15
16 # Move the left pointer towards the right as long as the color is the same as the first color
17 while colors[left_index] == colors[0]:
18 left_index += 1
19
20 # Move the right pointer towards the left as long as the color is the same as the first color
21 while colors[right_index] == colors[0]:
22 right_index -= 1
23
24 # Calculate the distance from the altered left and right pointers to the corresponding ends
25 # Take the maximum of these two distances to get the farthest distance with different colors
26 return max(num_colors - left_index - 1, right_index)
27
1class Solution {
2
3 public int maxDistance(int[] colors) {
4 // Length of the colors array.
5 int arrayLength = colors.length;
6
7 // If the first and last color are different, the maximum distance
8 // is the length of the array minus 1.
9 if (colors[0] != colors[arrayLength - 1]) {
10 return arrayLength - 1;
11 }
12
13 // Initialize indices 'left' and 'right' to the start and end of the array respectively.
14 int left = 0;
15 int right = arrayLength - 1;
16
17 // Increment 'left' index until we find a different color from the left end.
18 while (colors[++left] == colors[0]); // Empty loop body; iteration is done in the 'while' expression.
19
20 // Decrement 'right' index until we find a different color from the right end.
21 while (colors[--right] == colors[0]); // Empty loop body; iteration is done in the 'while' expression.
22
23 // Calculate the distance from the left-most different color to the right end,
24 // and from the left end to the right-most different color.
25 int leftDistance = arrayLength - left - 1;
26 int rightDistance = right;
27
28 // The maximum distance is the larger of 'leftDistance' and 'rightDistance'.
29 return Math.max(leftDistance, rightDistance);
30 }
31}
32
1class Solution {
2public:
3 int maxDistance(vector<int>& colors) {
4 int sizeOfColors = colors.size(); // The size of the colors vector
5 // Directly return the maximum possible distance if the first and last colors are different
6 if (colors[0] != colors[sizeOfColors - 1]) {
7 return sizeOfColors - 1;
8 }
9
10 int leftIndex = 0; // Initialize a left pointer at the start of the vector
11 int rightIndex = sizeOfColors; // Initialize a right pointer at the end of the vector
12
13 // Move the left pointer towards the right until we find a color different from the first color
14 while (colors[++leftIndex] == colors[0]);
15
16 // Move the right pointer towards the left until we find a color different from the first color
17 while (colors[--rightIndex] == colors[0]);
18
19 // Calculate the maximum distance possible from either ends
20 // by comparing the distance from the right-most different color to the beginning and
21 // the distance from the left-most different color to the end
22 return max(sizeOfColors - leftIndex - 1, rightIndex);
23 }
24};
25
1function maxDistance(colors: number[]): number {
2 const sizeOfColors = colors.length; // The size of the colors array
3
4 // Directly return the maximum possible distance if the first and last colors are different
5 if (colors[0] !== colors[sizeOfColors - 1]) {
6 return sizeOfColors - 1;
7 }
8
9 let leftIndex = 0; // Initialize a left pointer at the start of the array
10 let rightIndex = sizeOfColors - 1; // Initialize a right pointer at the end of the array
11
12 // Move the left pointer towards the right until we find a color different from the first color
13 while (colors[++leftIndex] === colors[0]);
14
15 // Move the right pointer towards the left until we find a color different from the last color
16 while (colors[--rightIndex] === colors[0]);
17
18 // Calculate the maximum distance possible from either end by comparing the distance from the right-most different color to the beginning and the distance from the left-most different color to the end. Return the larger of the two distances.
19 return Math.max(sizeOfColors - leftIndex - 1, rightIndex);
20}
21
22// Example usage:
23// const result = maxDistance([1, 1, 2, 1, 1]);
24// console.log(result); // This should output the maximum distance between two distinct colors.
25
Time and Space Complexity
Time Complexity
The time complexity of the given code can be analyzed based on the linear iterations it performs.
- Initial check for the first and last element:
O(1)
- as it is a direct comparison. - Two while loops to find the first index
i
from the start that has a different color and the first indexj
from the end that has a different color. Both of these while loops run inO(n)
time in the worst case, wheren
is the length of the colors list. However, each loop runs at most once per element and they do not iterate over the same elements multiple times.
The overall time complexity is dominated by the two while loops, which results in O(n)
(where n
is the number of elements in colors
).
Space Complexity
The space complexity of the code is analyzed by looking at the extra space required apart from the input.
- Constants
n
,i
, andj
are used for iterating and storing indices:O(1)
- constant space complexity as it does not depend on the input size. - No additional data structures or recursive calls that use additional space proportional to the input size.
Therefore, the space complexity of the given code is O(1)
(constant space complexity).
Learn more about how to find time and space complexity quickly using problem constraints.
What are the two properties the problem needs to have for dynamic programming to be applicable? (Select 2)
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Want a Structured Path to Master System Design Too? Don’t Miss This!