You are given an even integer n representing the number of houses arranged in a straight line, and a 2D array cost of size n x 3, where cost[i][j] represents the cost of painting house i with color j + 1.
The houses will look beautiful if they satisfy the following conditions:
n = 6, houses at positions (0, 5), (1, 4), and (2, 3) are considered equidistant.Return the minimum cost to paint the houses such that they look beautiful.
Example 1:
Input: n = 4, cost = [[3,5,7],[6,2,9],[4,8,1],[7,3,5]]
Output: 9
Explanation:
The optimal painting sequence is [1, 2, 3, 2] with corresponding costs [3, 2, 1, 3]. This satisfies the following conditions:
(1 != 2).(2 != 3).The minimum cost to paint the houses so that they look beautiful is 3 + 2 + 1 + 3 = 9.
Example 2:
Input: n = 6, cost = [[2,4,6],[5,3,8],[7,1,9],[4,6,2],[3,5,7],[8,2,4]]
Output: 18
Explanation:
The optimal painting sequence is [1, 3, 2, 3, 1, 2] with corresponding costs [2, 8, 1, 2, 3, 2]. This satisfies the following conditions:
(1 != 2).(3 != 1).(2 != 3).The minimum cost to paint the houses so that they look beautiful is 2 + 8 + 1 + 2 + 3 + 2 = 18.
Constraints:
2 <= n <= 105n is even.cost.length == ncost[i].length == 30 <= cost[i][j] <= 105When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The core idea is to try every single way to paint the houses. For each house, we consider all available color choices and calculate the total cost of that painting combination. We then choose the painting option with the lowest overall cost.
Here's how the algorithm would work step-by-step:
def paint_house_iv_brute_force(costs):
number_of_houses = len(costs)
number_of_colors = len(costs[0]) if number_of_houses > 0 else 0
minimum_cost = float('inf')
def calculate_total_cost(colors):
total_cost = 0
for house_index, color_index in enumerate(colors):
total_cost += costs[house_index][color_index]
return total_cost
def find_minimum_cost(house_index, current_colors):
nonlocal minimum_cost
# Base case: all houses have been painted
if house_index == number_of_houses:
total_cost = calculate_total_cost(current_colors)
minimum_cost = min(minimum_cost, total_cost)
return
# Try each color for the current house
for color_index in range(number_of_colors):
# Explore the possibility of painting the current house this color
find_minimum_cost(house_index + 1, current_colors + [color_index])
# Initiate the recursive calls to try every painting combination
find_minimum_cost(0, [])
#If minimum cost is unchanged, no houses or colors
if minimum_cost == float('inf'):
return 0
return minimum_costWe want to find the cheapest way to paint a row of houses, where each house can be painted one of several colors, and there's a cost for each color. The trick is to build up the best solution for each house one at a time, remembering the lowest costs from the previous houses.
Here's how the algorithm would work step-by-step:
def min_cost(house_costs, number_of_houses, number_of_colors):
if not house_costs or number_of_houses == 0 or number_of_colors == 0:
return 0
# Initialize cost for the first house.
previous_house_costs = house_costs[0]
for house_index in range(1, number_of_houses):
current_house_costs = house_costs[house_index]
new_costs = [0] * number_of_colors
# Calculate the minimum cost for each color.
for color_index in range(number_of_colors):
min_cost_excluding_current_color = float('inf')
# Find the minimum cost from the previous house, excluding the current color.
for previous_color_index in range(number_of_colors):
if previous_color_index != color_index:
min_cost_excluding_current_color = min(min_cost_excluding_current_color, previous_house_costs[previous_color_index])
# This is where we're building up the solution.
new_costs[color_index] = current_house_costs[color_index] + min_cost_excluding_current_color
previous_house_costs = new_costs
# After all houses, find the minimum of the costs of the last house.
return min(previous_house_costs)| Case | How to Handle |
|---|---|
| Empty costs array | Return 0 as no houses need painting, representing zero cost. |
| Empty costs for a specific house | Handle this as an invalid input, potentially throwing an exception or returning a default large value to indicate impossible cost. |
| Only one house to paint (costs array length of 1) | Return the minimum cost within the single row, as we only need to paint this one house. |
| Only one color available | Sum all the costs for the color, as we have no choice but to paint every house using the same color. |
| Large number of houses and colors, leading to potential integer overflow when summing costs | Use a larger data type like long to store intermediate and final cost values to prevent overflow. |
| All costs are extremely large values (close to the maximum integer) | Be cautious about integer overflows when calculating minimum costs and consider using a larger data type if needed. |
| Forbidden adjacent colors cause no possible solution | Return a sentinel value (e.g., -1 or Infinity) when no valid combination of colors satisfies the constraints and allows to paint all houses |
| Costs array contains negative values | Handle this as an invalid input as costs cannot be negative; throw an exception or return an error value. |