You are given two integers, n
and k
, along with two 2D integer arrays, stayScore
and travelScore
.
A tourist is visiting a country with n
cities, where each city is directly connected to every other city. The tourist's journey consists of exactly k
0-indexed days, and they can choose any city as their starting point.
Each day, the tourist has two choices:
curr
during day i
, they will earn stayScore[i][curr]
points.curr
to city dest
, they will earn travelScore[curr][dest]
points.Return the maximum possible points the tourist can earn.
Example 1:
Input: n = 2, k = 1, stayScore = [[2,3]], travelScore = [[0,2],[1,0]]
Output: 3
Explanation:
The tourist earns the maximum number of points by starting in city 1 and staying in that city.
Example 2:
Input: n = 3, k = 2, stayScore = [[3,4,2],[2,1,2]], travelScore = [[0,2,1],[2,0,4],[3,2,0]]
Output: 8
Explanation:
The tourist earns the maximum number of points by starting in city 1, staying in that city on day 0, and traveling to city 2 on day 1.
Constraints:
1 <= n <= 200
1 <= k <= 200
n == travelScore.length == travelScore[i].length == stayScore[i].length
k == stayScore.length
1 <= stayScore[i][j] <= 100
0 <= travelScore[i][j] <= 100
travelScore[i][i] == 0
When 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 brute force approach explores every single possible path the tourist could take through all the available locations. We calculate the total points earned for each of these paths. Finally, we choose the path that yields the highest total points.
Here's how the algorithm would work step-by-step:
def maximum_points_tourist_brute_force(points):
number_of_locations = len(points)
maximum_points = 0
def explore_paths(current_location, visited_locations, current_points):
nonlocal maximum_points
visited_locations = set(visited_locations)
visited_locations.add(current_location)
current_points += points[current_location]
# Update maximum points found so far.
maximum_points = max(maximum_points, current_points)
# Explore all possible next locations.
for next_location in range(number_of_locations):
if next_location not in visited_locations:
# Recursively explore the path from the next location.
explore_paths(next_location, list(visited_locations), current_points)
# Iterate through each location as a potential starting point.
for start_location in range(number_of_locations):
# Initiate exploration from the starting location.
explore_paths(start_location, [], 0)
return maximum_points
The key to maximizing points is realizing that we can solve this problem sequentially. Instead of trying every combination of routes, we make the best decision at each location, knowing it leads to the overall best score. This is similar to planning a road trip where each stop is chosen to maximize your enjoyment.
Here's how the algorithm would work step-by-step:
def maximum_points_tourist_can_earn(points, paths, start_city, end_city):
number_of_cities = len(points)
maximum_points = [float('-inf')] * number_of_cities
maximum_points[start_city] = points[start_city]
visited = [False] * number_of_cities
current_city = start_city
while not visited[end_city]:
visited[current_city] = True
# Iterate over all possible next cities.
for next_city in range(number_of_cities):
if paths[current_city][next_city] == 1 and not visited[next_city]:
# Check if path exists and is unvisited
new_points = maximum_points[current_city] + points[next_city]
# Choose the path that yields the highest score.
if new_points > maximum_points[next_city]:
maximum_points[next_city] = new_points
best_next_city = -1
best_next_city_points = float('-inf')
# Find the unvisited city with the highest points
for city_index in range(number_of_cities):
if not visited[city_index] and maximum_points[city_index] > best_next_city_points:
best_next_city = city_index
best_next_city_points = maximum_points[city_index]
if best_next_city == -1:
break
current_city = best_next_city
return maximum_points[end_city]
Case | How to Handle |
---|---|
points array is null or empty | Return 0 if points is null or empty, as there are no locations to visit. |
max_distance is 0 | Return points[0] if max_distance is 0, as the tourist can only stay at the starting location. |
points array has only one element | Return points[0] if points has only one element, as that's the only location. |
All points are 0 | Return 0, as the tourist cannot earn any points regardless of the path taken. |
All points are negative | Use dynamic programming approach to find the maximum sum, even if all values are negative, the algorithm chooses the least negative values. |
max_distance is larger than the array length | Iterate through the entire array, as the tourist can reach any location from the starting point. |
Large input size that could cause recursion depth issues | Use dynamic programming (DP) with memoization instead of recursion to avoid stack overflow errors. |
Integer overflow when summing points | Use a data type with larger capacity (e.g., long) to store the accumulated points. |