Open In App

Finding Nearest Stores for each Houses

Last Updated : 13 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given two arrays representing integer locations of stores[] and houses[] (each location in this problem is one-dimensional). The task is to find an integer array result[], where result[i] should denote the location of the store closest to the i-th house. If many stores are equidistant from a particular house, choose the store with the smallest numerical location.

Note: There may be multiple stores and houses at the same location.

Examples:

Input: houses = [5, 10, 17], stores = [1, 5, 20, 11, 16]
Output: [5, 11, 16]
Explanation: The closest store to the house at location 5 is the store at the same location.
The closest store to the house at location 10 is the store at the location 11.
The closest store to the house at location 17 is the store at the location 16.

Input: houses = [2, 4, 2], stores = [5, 1, 2, 3]
Output: [2, 3, 2]

Input: houses = [4, 8, 1, 1], stores = [5, 3, 1, 2, 6]
Output: [3, 6, 1, 1]

Finding Nearest Stores for each Houses using Binary Search:

The idea behind use binary search for search the closest stores for each houses. First sort the order of store locations. By performing binary search, we can quickly locate the nearest store to each house, optimizing the search process. This approach minimizes the time complexity and efficiently finds the closest store for each house, making it a great choice when dealing with a large number of houses and stores.

Step-by-step approach:

  • For each house, uses the lower_bound() function to find the store location that is greater than or equal to the current house location.
    • If the located store matches the house’s location, added this location to the result.
    • If the located store is different from the house’s location,
    • Calculates the distances to the left and right stores then selects the closer store as the nearest one and adds it to the result.
    • If there is no store to the left, adds the closest store to the right to the result.
  • Finally, returns the result array.

Below is the implementation of the above approch.

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to find the closest store for each house
vector<int> closestStore(vector<int>& houses,
                         vector<int>& stores)
{
 
    // Sort the store locations in ascending order for
    // efficient searching
    sort(stores.begin(), stores.end());
 
    // Initialize a vector to store the results
    vector<int> result;
 
    // Iterate through each house
    for (int i = 0; i < houses.size(); i++) {
 
        // Use lower_bound to find the first store location
        // greater than or equal to the current house
        auto l = lower_bound(stores.begin(), stores.end(),
                             houses[i]);
 
        if (l != stores.end()) {
            if (*l == houses[i]) {
 
                // If the current store location matches the
                // house location, add it to the result
                result.push_back(*l);
            }
            else {
 
                // Create a pointer for the right store
                // location
                auto r = l;
 
                // Check if there is a store location to the
                // left
                if (--l != stores.begin()) {
 
                    // Calculate the distances to the left
                    // and right stores
                    int closestStoreToLeft
                        = abs(houses[i] - *l);
                    int closestStoreToRight
                        = abs(houses[i] - *r);
 
                    // Choose the closer store and add it to
                    // the result
                    if (closestStoreToLeft
                        <= closestStoreToRight) {
                        result.push_back(*l);
                    }
                    else {
                        result.push_back(*r);
                    }
                }
                else {
 
                    // If no left store exists, add the
                    // closest right store to the result
                    result.push_back(*l);
                }
            }
        }
        else {
 
            // If there is no store to the right, add the
            // closest store to the left to the result
            result.push_back(*(--l));
        }
    }
 
    // Return the vector containing the closest store for
    // each house
    return result;
}
 
// Driver code
int main()
{
    vector<int> houses = { 4, 8, 1, 1 };
    vector<int> stores = { 5, 3, 1, 2, 6 };
 
    vector<int> result = closestStore(houses, stores);
 
    // Print the closest store for each house
    for (auto i : result) {
        cout << i << " ";
    }
 
    return 0;
}


Java




import java.util.*;
 
public class ClosestStore {
 
    // Function to find the closest store for each house
    public static List<Integer> closestStore(List<Integer> houses, List<Integer> stores) {
 
        // Sort the store locations in ascending order for efficient searching
        Collections.sort(stores);
 
        // Initialize a list to store the results
        List<Integer> result = new ArrayList<>();
 
        // Iterate through each house
        for (int house : houses) {
 
            // Use binary search (Collections.binarySearch) to find the first store location
            // greater than or equal to the current house
            int idx = Collections.binarySearch(stores, house);
 
            if (idx >= 0) {
                // If the current store location matches the house location, add it to the result
                result.add(stores.get(idx));
            } else {
                idx = -idx - 1; // Convert the negative insertion point to the correct index
 
                // Check if there is a store location to the left
                if (idx > 0 && idx < stores.size()) {
                    // Calculate the distances to the left and right stores
                    int closestStoreToLeft = Math.abs(house - stores.get(idx - 1));
                    int closestStoreToRight = Math.abs(house - stores.get(idx));
 
                    // Choose the closer store and add it to the result
                    if (closestStoreToLeft <= closestStoreToRight) {
                        result.add(stores.get(idx - 1));
                    } else {
                        result.add(stores.get(idx));
                    }
                } else if (idx == 0) {
                    // If no left store exists, add the closest right store to the result
                    result.add(stores.get(idx));
                } else {
                    // If there is no store to the right, add the closest store to the left to the result
                    result.add(stores.get(idx - 1));
                }
            }
        }
 
        // Return the list containing the closest store for each house
        return result;
    }
 
    // Driver code
    public static void main(String[] args) {
        List<Integer> houses = Arrays.asList(4, 8, 1, 1);
        List<Integer> stores = Arrays.asList(5, 3, 1, 2, 6);
 
        List<Integer> result = closestStore(houses, stores);
 
        // Print the closest store for each house
        for (int i : result) {
            System.out.print(i + " ");
        }
    }
}


Python3




def closest_store(houses, stores):
    # Sort the store locations in ascending order for efficient searching
    stores.sort()
 
    # Initialize a list to store the results
    result = []
 
    # Iterate through each house
    for house in houses:
        # Use bisect_left to find the first store location greater than or equal to the current house
        index = bisect.bisect_left(stores, house)
 
        if index != len(stores):
            if stores[index] == house:
                # If the current store location matches the house location, add it to the result
                result.append(stores[index])
            else:
                # Check if there is a store location to the left
                if index > 0:
                    # Calculate the distances to the left and right stores
                    closest_store_to_left = abs(house - stores[index - 1])
                    closest_store_to_right = abs(house - stores[index])
 
                    # Choose the closer store and add it to the result
                    if closest_store_to_left <= closest_store_to_right:
                        result.append(stores[index - 1])
                    else:
                        result.append(stores[index])
                else:
                    # If no left store exists, add the closest right store to the result
                    result.append(stores[index])
        else:
            # If there is no store to the right, add the closest store to the left to the result
            result.append(stores[index - 1])
 
    # Return the list containing the closest store for each house
    return result
 
# Driver code
if __name__ == "__main__":
    import bisect
 
    houses = [4, 8, 1, 1]
    stores = [5, 3, 1, 2, 6]
 
    result = closest_store(houses, stores)
 
    # Print the closest store for each house
    for i in result:
        print(i, end=" ")
#This code is contributed by utkarsh


C#




using System;
using System.Collections.Generic;
 
class Program
{
    // Function to find the closest store for each house
    static List<int> ClosestStore(List<int> houses, List<int> stores)
    {
        // Sort the store locations in ascending order for efficient searching
        stores.Sort();
 
        // Initialize a list to store the results
        List<int> result = new List<int>();
 
        // Iterate through each house
        foreach (int house in houses)
        {
            // Use BinarySearch to find the index of the first store location
            // greater than or equal to the current house
            int index = stores.BinarySearch(house);
 
            // If the house exactly matches a store location, add it to the result
            if (index >= 0)
            {
                result.Add(stores[index]);
            }
            else
            {
                // If the house doesn't exactly match a store location
                // Find the index of the store to the right and left of the house
                int rightIndex = ~index;
                int leftIndex = rightIndex - 1;
 
                // Calculate the distances to the left and right stores
                int closestStoreToLeft = leftIndex >= 0 ? house - stores[leftIndex] : int.MaxValue;
                int closestStoreToRight = rightIndex < stores.Count ? stores[rightIndex] - house : int.MaxValue;
 
                // Choose the closer store and add it to the result
                if (closestStoreToLeft <= closestStoreToRight)
                {
                    result.Add(stores[leftIndex]);
                }
                else
                {
                    result.Add(stores[rightIndex]);
                }
            }
        }
 
        // Return the list containing the closest store for each house
        return result;
    }
 
    // Driver code
    static void Main(string[] args)
    {
        List<int> houses = new List<int> { 4, 8, 1, 1 };
        List<int> stores = new List<int> { 5, 3, 1, 2, 6 };
 
        List<int> result = ClosestStore(houses, stores);
 
        // Print the closest store for each house
        foreach (int store in result)
        {
            Console.Write(store + " ");
        }
    }
}


Javascript




// Function to find the closest store for each house
function closestStore(houses, stores) {
    // Sort the store locations in ascending order for efficient searching
    stores.sort((a, b) => a - b);
 
    // Initialize a array to store the results
    let result = [];
 
    // Iterate through each house
    for (let i = 0; i < houses.length; i++) {
        // Use binary search to find the first store location greater than or equal to the current house
        let l = stores.findIndex(store => store >= houses[i]);
 
        if (l !== -1) {
            if (stores[l] === houses[i]) {
                // If the current store location matches the house location, add it to the result
                result.push(stores[l]);
            } else {
                // Create a pointer for the right store location
                let r = l;
 
                // Check if there is a store location to the left
                if (l - 1 >= 0) {
                    // Calculate the distances to the left and right stores
                    let closestStoreToLeft = Math.abs(houses[i] - stores[l - 1]);
                    let closestStoreToRight = Math.abs(houses[i] - stores[r]);
 
                    // Choose the closer store and add it to the result
                    if (closestStoreToLeft <= closestStoreToRight) {
                        result.push(stores[l - 1]);
                    } else {
                        result.push(stores[r]);
                    }
                } else {
                    // If no left store exists, add the closest right store to the result
                    result.push(stores[r]);
                }
            }
        } else {
            // If there is no store to the right, add the closest store to the left to the result
            result.push(stores[stores.length - 1]);
        }
    }
 
    // Return the array containing the closest store for each house
    return result;
}
 
// Driver code
function main() {
    let houses = [4, 8, 1, 1];
    let stores = [5, 3, 1, 2, 6];
 
    let result = closestStore(houses, stores);
 
    // Print the closest store for each house
    console.log(result.join(" "));
}
 
// Run the main function
main();
//This code is contributed byt Utkarsh


Output

3 6 1 1 



Time Complexity: O(M*log(M) + N*log(M)), where N and M are the length of houses and stores respectively.
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads