Leetcode!
  • LeetCode!
  • My personal guide to Leetcode
  • Array
    • 11. Container With Most Water
    • 15. 3Sum
    • 219. Contains Duplicate II
    • 238. Product of Array Except Self
    • 245. Shortest Word Distance III
    • 392. Is Subsequence
    • 442. Find All Duplicates in an Array
    • 561. Array Partition I
    • 661. Image Smoother
    • 697. Degree of an Array
    • 723. Candy Crush
    • 832. Flipping an Image
  • Backtracking
    • 294. Flip Game II
    • 401. Binary Watch
    • 1079. Letter Tile Possibilities
  • Binary Search
    • 744. Find Smallest Letter Greater Than Target
    • 852. Peak Index in a Mountain Array
  • String
    • 6. ZigZag Conversion
    • 17. Letter Combinations of a Phone Number
    • 38. Count and Say
    • 521. Longest Uncommon Subsequence I
    • 544. Output Contest Matches
    • 937. Reorder Data in Log Files
  • Design
    • 251. Flatten 2D Vector
    • 281. Zigzag Iterator
  • Hash Table
    • 1. Two Sum
    • 508. Most Frequent Subtree Sum
    • 884. Uncommon Words from Two Sentences
    • 734. Sentence Similarity
  • Linked List
    • 2. Add Two Numbers
  • Unsorted
    • 917. Reverse Only Letters
  • Math
    • 43. Multiply Strings
    • 462. Minimum Moves to Equal Array Elements II
    • 553. Optimal Division
    • 800. Similar RGB Color
  • Greedy
    • 406. Queue Reconstruction by Height
    • 861. Score After Flipping Matrix
  • Tree
    • 701. Insert into a Binary Search Tree
    • 897. Increasing Order Search Tree
  • Divide and Conquer
    • 53. Maximum Subarray
  • Dynamic Programming
    • 62. Unique Paths
    • 63. Unique Paths II
    • 64. Minimum Path Sum
    • 120. Triangle
    • 198. House Robber
    • 213. House Robber II
    • 303. Range Sum Query - Immutable
    • 518. Coin Change 2
    • 750. Number Of Corner Rectangles
    • 337. House Robber III
  • Depth first search
    • 841. Keys and Rooms
  • Trie
    • 677. Map Sum Pairs
  • Two pointer
    • 42. Trapping Rain Water
Powered by GitBook
On this page
  • Approach 1: Hash Map
  • Approach 2: Minor optimization to approach 1
  1. Dynamic Programming

750. Number Of Corner Rectangles

Approach 1: Hash Map

from collections import defaultdict
class Solution(object):
    def countCornerRectangles(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        R, C = len(grid), len(grid[0])
        if R == 1 or C == 1:
            return 0
        rs = defaultdict(set)
        for i in range(R):
            for j in range(C):
                if grid[i][j] == 1:
                    rs[i].add(j)
        count = 0
        rsl = {}
        for i in rs:
            rsl[i] = len(rs[i])
        for i in rs:
            for j in rs:
                if i != j:
                    n = len(rs[i] - rs[j])
                    if n != rsl[i]:
                        n = rsl[i] - n
                        count += (n * (n-1))/2
        return count/2

We start off by indexing the matrix and converting it into a dictionary, where the positions of all the ones are stored in a hash map. The key is the row number and the value associated with that is a set of column numbers that have a 1 in that row.

After that we look for rows that have common indices and append the number of squares that can be formed using the number of common indices. That number can be found by a bit of math. If n is the number of common indices, then nC2 or n Choose 2 is the number of rectangles that can be formed with those.

We keep a counter that keeps track of the number of rectangles we've seen.

Since we're double counting [(i,j) and (j,i) will both be added] I divide by 2 before returning

Time Complexity: O(R*C^2)

Space Complexity: O(R*C)

Approach 2: Minor optimization to approach 1

class Solution(object):
    def countCornerRectangles(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        R, C = len(grid), len(grid[0])
        if R == 1 or C == 1:
            return 0
        rs = {}
        for i in range(R):
            rs[i] = set()
            for j in range(C):
                if grid[i][j] == 1:
                    rs[i].add(j)
        count = 0
        rsl, rows, le = {}, [], 0
        for i in rs:
            rsl[i] = len(rs[i])
            rows.append(i)
            le += 1
        for i in range(le):
            for j in range(i+1, le):
                n = rsl[rows[i]] - len(rs[rows[i]] - rs[rows[j]])
                count += (n * (n-1))/2
        return count

Very minor improvement, only went from 63% to 72% but stopped double counting and removed an external library

Time Complexity: O(R*C^2)

Space Complexity: O(R*C)

Previous518. Coin Change 2Next337. House Robber III

Last updated 6 years ago