Intuting
  • Untitled
  • Algorithm Interviews
    • Common Manager
    • Least # of Activities
    • Real Estate Agent
    • Palindrome Pairs
    • Mirror Tree
    • Ship Cargo in 5 Days
  • Coding Interviews
    • Linux "Find" Command
    • Amazon Locker Service
    • Cache Analysis Service
    • Zookeeper Service
  • System Design Interviews
    • Event Reservation System
Powered by GitBook
On this page
  • Question
  • Explanation Video
  • Brute-force Approach
  • Optimization on Price Calculation

Was this helpful?

  1. Algorithm Interviews

Real Estate Agent

#Amazon #Hard #DynamicProgramming

PreviousLeast # of ActivitiesNextPalindrome Pairs

Last updated 5 years ago

Was this helpful?

Question

Given a 2D matrix of prices and a budget, find the biggest rectangular area you can purchase with the given budget.

Explanation Video

Brute-force Approach

Visit every possible rectangular areas in the given 2D array and find the biggest area that is under the given budget.

  • Time complexity: O(n6)

  • Space complexity: O(1)

  
  private int solve(int[][] prices, int budget) {
    int biggestArea = Integer.MIN_VALUE;

    // First two loops determine the top-left corner of the rectangles.
    for (int x = 0; x < prices.length; x++) {
      for (int y = 0; y < prices[x].length; y++) {

        // The following two loops determine the width & height of the rectangles.
        for (int width = 1; width <= prices.length - x; width++) {
          for (int height = 1; height <= prices[x].length - y; height++) {

            // Compute the price of the given rectangle &
            // Determine whether to update the max area or not.
            int currentPrice = calculatePrice(prices, x, y, width, height);
            if (currentPrice <= budget) {
              int currentArea = width * height;
              biggestArea = Integer.max(biggestArea, currentArea);
            }
          }
        }
      }
    }

    return biggestArea;
  }
  
  // Calculates the price of the given rectangular area. 
  private int calculatePrice(int[][] prices, int x, int y, int width, int height) {
    int sum = 0;
    for (int i = 0; i < width; i++) {
      for (int j = 0; j < height; j++) {
        sum += prices[x + i][y + j];
      }
    }

    return sum;
  }

Optimization on Price Calculation

Use dynamic programming to pre-compute prices. Improve the time complexity by trading off w/ space.

  • Time complexity: O(n4)

  • Space complexity: O(n2)

  
  private int solve(int[][] prices, int budget) {

    // This pre-computed prices will be used to calculate prices in the loops below.
    int[][] precomputedPrices = generatePrecomputedPrices(prices);
    int biggestArea = Integer.MIN_VALUE;

    // First two loops determine the top-left corner of the rectangles.
    for (int x = 0; x < prices.length; x++) {
      for (int y = 0; y < prices[x].length; y++) {

        // The following two loops determine the width & height of the rectangles.
        for (int width = 1; width <= prices.length - x; width++) {
          for (int height = 1; height <= prices[x].length - y; height++) {

            // Compute the price of the given rectangle &
            // Determine whether to update the max area or not.
            int currentPrice = calculatePrice(precomputedPrices, x, y, width, height);
            if (currentPrice <= budget) {
              int currentArea = width * height;
              biggestArea = Integer.max(biggestArea, currentArea);
            }
          }
        }
      }
    }

    return biggestArea;
  }

  // Calculates the price of the given rectangular area with the pre-computed prices.
  private int calculatePrice(
          int[][] precomputedPrices, int x, int y, int width, int height) {
    int totalPrice = precomputedPrices[x + width - 1][y + height - 1];
    if (x > 0) totalPrice -= precomputedPrices[x - 1][y + height - 1];
    if (y > 0) totalPrice -= precomputedPrices[x + width - 1][y - 1];
    if (x > 0 && y > 0) totalPrice += precomputedPrices[x - 1][y - 1];

    return totalPrice;
  }

  // Compute prices of rectangles w/ a fixed top-left corner as (0,0).
  private int[][] generatePrecomputedPrices(int[][] prices) {
    int[][] precomputedPrices = new int[prices.length][prices[0].length];

    // Pre-compute the first row.
    precomputedPrices[0][0] = prices[0][0];
    for (int x = 1; x < precomputedPrices.length; x++) {
      precomputedPrices[x][0] = precomputedPrices[x - 1][0] + prices[x][0];
    }

    // Pre-compute the first column
    for (int y = 1; y < precomputedPrices[0].length; y++) {
      precomputedPrices[0][y] = precomputedPrices[0][y - 1] + prices[0][y];
    }

    // Pre-compute the rest.
    for (int x = 1; x < precomputedPrices.length; x++) {
      for (int y = 1; y < precomputedPrices[x].length; y++) {
        precomputedPrices[x][y] =
            precomputedPrices[x - 1][y]
                + precomputedPrices[x][y - 1]
                - precomputedPrices[x - 1][y - 1]
                + prices[x][y];
      }
    }

    return precomputedPrices;
  }
Explain how to approach the question and coding explanation as well.