Taro Logo

Coordinate With Maximum Network Quality

#25 Most AskedMedium
18 views
Topics:
Arrays

You are given an array of network towers towers, where towers[i] = [xi, yi, qi] denotes the ith network tower with location (xi, yi) and quality factor qi. All the coordinates are integral coordinates on the X-Y plane, and the distance between the two coordinates is the Euclidean distance.

You are also given an integer radius where a tower is reachable if the distance is less than or equal to radius. Outside that distance, the signal becomes garbled, and the tower is not reachable.

The signal quality of the ith tower at a coordinate (x, y) is calculated with the formula ⌊qi / (1 + d)⌋, where d is the distance between the tower and the coordinate. The network quality at a coordinate is the sum of the signal qualities from all the reachable towers.

Return the array [cx, cy] representing the integral coordinate (cx, cy) where the network quality is maximum. If there are multiple coordinates with the same network quality, return the lexicographically minimum non-negative coordinate.

Note:

  • A coordinate (x1, y1) is lexicographically smaller than (x2, y2) if either:
    • x1 < x2, or
    • x1 == x2 and y1 < y2.
  • ⌊val⌋ is the greatest integer less than or equal to val (the floor function).

Example 1:

Input: towers = [[1,2,5],[2,1,7],[3,1,9]], radius = 2
Output: [2,1]
Explanation: At coordinate (2, 1) the total quality is 13.
- Quality of 7 from (2, 1) results in ⌊7 / (1 + sqrt(0)⌋ = ⌊7⌋ = 7
- Quality of 5 from (1, 2) results in ⌊5 / (1 + sqrt(2)⌋ = ⌊2.07⌋ = 2
- Quality of 9 from (3, 1) results in ⌊9 / (1 + sqrt(1)⌋ = ⌊4.5⌋ = 4
No other coordinate has a higher network quality.

Example 2:

Input: towers = [[23,11,21]], radius = 9
Output: [23,11]
Explanation: Since there is only one tower, the network quality is highest right at the tower's location.

Example 3:

Input: towers = [[1,2,13],[2,1,7],[0,1,9]], radius = 2
Output: [1,2]
Explanation: Coordinate (1, 2) has the highest network quality.

Constraints:

  • 1 <= towers.length <= 50
  • towers[i].length == 3
  • 0 <= xi, yi, qi <= 50
  • 1 <= radius <= 50

Solution


Clarifying Questions

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:

  1. What are the constraints on the coordinate values (xi, yi) and the quality factor qi? Are they integers, and what is their range?
  2. What is the range of the radius? Is it always a positive integer?
  3. If multiple coordinates have the same maximum network quality, what does 'lexicographically smallest' specifically mean in terms of comparing [x, y] coordinates?
  4. Can the input array towers be empty? If so, what should I return?
  5. Is there a practical upper bound on the x and y coordinates I need to consider when searching for the optimal location?

Brute Force Solution

Approach

To find the best spot for a cell tower, we'll check every possible location within a certain range. At each location, we calculate the network quality based on nearby existing towers and then keep track of the location with the highest quality.

Here's how the algorithm would work step-by-step:

  1. First, figure out the smallest and largest coordinate values among all the existing cell tower locations. This defines the square area we need to check.
  2. Then, start checking network quality at every possible spot within that square area. Imagine overlaying a grid on the area and testing each point on the grid.
  3. For each potential spot, calculate its network quality. This is done by looking at all the existing towers and seeing how strong their signal is at that spot, taking into account the distance and the maximum range of each tower.
  4. Keep track of the spot that gives the highest network quality so far.
  5. After checking all the spots on the grid, the spot we kept track of is the best location for the new cell tower.

Code Implementation

def best_coordinate(towers, radius):
    min_x = float('inf')
    min_y = float('inf')
    max_x = float('-inf')
    max_y = float('-inf')

    for x, y, _ in towers:
        min_x = min(min_x, x)
        min_y = min(min_y, y)
        max_x = max(max_x, x)
        max_y = max(max_y, y)

    best_quality = 0
    best_coordinate_x = 0
    best_coordinate_y = 0

    # Iterate through all possible coordinates.
    for coordinate_x in range(min_x, max_x + 1):

        for coordinate_y in range(min_y, max_y + 1):
            current_quality = 0

            # Calculate quality at current coordinate.
            for tower_x, tower_y, quality in towers:

                distance = ((coordinate_x - tower_x)**2 + (coordinate_y - tower_y)**2)**0.5

                if distance <= radius:
                    current_quality += int(quality / (1 + distance))

            # Update best coordinate if necessary.
            if current_quality > best_quality:

                best_quality = current_quality

                best_coordinate_x = coordinate_x

                best_coordinate_y = coordinate_y

            #Tie breaker condition
            elif current_quality == best_quality:

                if coordinate_x < best_coordinate_x:

                    best_coordinate_x = coordinate_x

                    best_coordinate_y = coordinate_y

                elif coordinate_x == best_coordinate_x and coordinate_y < best_coordinate_y:

                    best_coordinate_y = coordinate_y

    #Return the co-ordinates with the maximum network quality
    return [best_coordinate_x, best_coordinate_y]

Big(O) Analysis

Time Complexity
O(R² * N)Let R be the range of coordinates to check, determined by the difference between the maximum and minimum x and y coordinates of the existing towers, effectively defining a square grid of size R x R. We iterate through all possible coordinate pairs (i, j) within this R x R grid, which takes O(R²) time. For each coordinate pair, we iterate through all N existing tower locations to calculate the network quality at that point. Therefore, calculating the network quality for each coordinate takes O(N) time. Thus, the overall time complexity is O(R² * N), reflecting the cost of checking each location against every tower.
Space Complexity
O(1)The algorithm iterates through possible locations within a defined area based on the existing tower coordinates, but it does not create any auxiliary data structures to store intermediate results or visited locations. It only keeps track of the spot with the highest network quality so far, which can be done using a few variables to store the best coordinates and the corresponding quality. Therefore, the space used remains constant, independent of the number of existing towers (N), and the auxiliary space complexity is O(1).

Optimal Solution

Approach

The best location is the one with the highest total signal strength from nearby towers. We don't want to check every single possible location. We will use a clever trick to limit our search area and avoid unnecessary calculations.

Here's how the algorithm would work step-by-step:

  1. First, find the smallest and largest x and y coordinates among all the tower locations to create a bounding box.
  2. Only check locations inside this box, since locations outside cannot possibly have a better signal.
  3. Decide on a grid spacing (e.g., check every whole number coordinate). Smaller spacing results in a better, but slower, result.
  4. For each grid point inside the bounding box, calculate the total signal strength from all towers.
  5. Keep track of the location with the highest signal strength you've seen so far.
  6. After checking all grid points, the location you saved is your answer.

Code Implementation

def coordinate_with_maximum_network_quality(towers, radius):
    min_x = float('inf')
    min_y = float('inf')
    max_x = float('-inf')
    max_y = float('-inf')

    # Find boundaries to limit the search area.
    for x, y, _ in towers:
        min_x = min(min_x, x)
        min_y = min(min_y, y)
        max_x = max(max_x, x)
        max_y = max(max_y, y)

    best_x = -1
    best_y = -1
    max_quality = 0

    # Iterate only within the derived bounds.
    for test_x in range(int(min_x), int(max_x) + 1):
        for test_y in range(int(min_y), int(max_y) + 1):
            current_quality = 0
            for tower_x, tower_y, signal_strength in towers:
                distance = ((test_x - tower_x)**2 + (test_y - tower_y)**2)**0.5
                if distance <= radius:
                    current_quality += int(signal_strength / (1 + distance))

            # Update best location if current is better.
            if current_quality > max_quality:
                max_quality = current_quality
                best_x = test_x
                best_y = test_y
            elif current_quality == max_quality:
                if test_x < best_x or (test_x == best_x and test_y < best_y):
                    best_x = test_x
                    best_y = test_y

    return [best_x, best_y]

Big(O) Analysis

Time Complexity
O(R * C * n)Let n be the number of towers. The algorithm first finds the bounding box by iterating through all towers, which takes O(n) time. Then, it iterates through all grid points within this bounding box. Let R be the number of rows and C be the number of columns (i.e., width and height) of this grid. For each grid point (R * C in total), the algorithm calculates the signal strength from all n towers, taking O(n) time. Thus, the overall time complexity is dominated by the nested loops for the grid and the towers which gives O(R * C * n). Since the bounding box size is independent of n, R and C can be considered fixed relative to n.
Space Complexity
O(1)The algorithm primarily uses a fixed number of variables to store the bounding box coordinates (smallest and largest x, y), the current grid point being checked, the maximum signal strength found so far, and the corresponding coordinate. The space used for these variables is constant and does not depend on the number of towers (N). Therefore, the auxiliary space complexity is O(1).

Edge Cases

towers is null or empty
How to Handle:
Return [0, 0] as the problem statement dictates, indicating no towers present.
radius is zero
How to Handle:
Only the tower at the coordinate itself contributes to the network quality, so iterate through towers and return the coordinates of the highest quality tower.
All towers are at the same location with different qualities
How to Handle:
The result should be the location of the towers, with the sum of all qualities as the maximum quality.
Towers have negative coordinates
How to Handle:
The coordinate search space should accommodate negative values to find the true optimum.
Integer overflow in distance calculation or quality calculation
How to Handle:
Use long or double for intermediate calculations of distance and quality to avoid integer overflow.
Large radius value that encompasses all towers
How to Handle:
The network quality calculation should still function correctly and sum the contributions from all towers within the large radius.
Towers with very high quality values
How to Handle:
Intermediate calculations should use larger datatypes like 'long' to avoid overflow when summing signal values, preventing incorrect results.
Floating-point precision issues in distance calculation
How to Handle:
Consider a small epsilon value for comparing distances if precise equality is needed to handle slight calculation errors.
0/25 completed