1. 程式人生 > >【LeetCode】939. Minimum Area Rectangle 解題報告(Python)

【LeetCode】939. Minimum Area Rectangle 解題報告(Python)

作者: 負雪明燭
id: fuxuemingzhu
個人部落格: http://fuxuemingzhu.cn/


目錄

題目地址:https://leetcode.com/problems/minimum-area-rectangle/description/

題目描述

Given a set of points in the xy-plane, determine the minimum area of a rectangle formed from these points, with sides parallel to the x

and y axes.

If there isn’t any rectangle, return 0.

Example 1:

Input: [[1,1],[1,3],[3,1],[3,3],[2,2]]
Output: 4

Example 2:

Input: [[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]]
Output: 2

Note:

  1. 1 <= points.length <= 500
  2. 0 <= points[i][0] <= 40000
  3. 0 <= points[i][1] <= 40000
  4. All points are distinct.

題目大意

給了很多點,找出這些點中,任意選擇4個點,形成一個長方形,要求長方形的邊必須平行與座標軸。求最小面積的長方形的面積是多少。

解題方法

確定對角線,找另外兩點(4sum)

周賽的第三題,超時了很多次,確實需要優秀的解法才能通過。

最原始的想法就是,我們找出和座標軸平行的三個點,來確定第四個點。這麼做的話,時間複雜度是O(N^3),果然超時了。這說明我對4sum理解還不夠深刻啊!兩天前剛做過的454. 4Sum II,做法就是確定兩個數字的和,然後看剩餘的兩個數字的和是否存在即可。也就是說4sum的時間複雜度只有O(N^2)。

這個題正確的做法是先確定對角線兩個點!題目要求所有的邊必須平行座標軸,就是告訴我們只用確定對角線兩個元素,剩餘的兩個點可以直接求出來即可!因此不需要確定3個點的O(N^3)的遍歷。

所以啊,還是需要活學活用才行啊!

時間複雜度是O(N^2),空間複雜度是O(N)。

class Solution(object):
    def minAreaRect(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        points = map(tuple, points)
        points.sort()
        pset = set(points)
        N = len(points)
        res = float('inf')
        for i in range(N - 1):
            p1 = points[i]
            for j in range(i + 1, N):
                p4 = points[j]
                if p4[0] == p1[0] or p4[1] == p1[1]:
                    continue
                p2 = (p1[0], p4[1])
                p3 = (p4[0], p1[1])
                if p2 in pset and p3 in pset:
                    res = min(res, abs(p3[0] - p1[0]) * abs(p2[1] - p1[1]))
        return res if res != float("inf") else 0

字典儲存出現的x值,y值的點

另一個高效的演算法是使用字典進行儲存。這樣的話,如果我們確定了一個點(x,y),那麼可以快速找到和它相同x座標或者y座標的所有點,然後只用遍歷這些點就行了。

具體做法是,使用兩個字典xdict和ydict,儲存每個x,y對應的座標。然後對相同的x進行O(N^2)的遍歷。這時相當於確定了相同x的兩個點,然後對相同的y再進行遍歷,這樣確定了第三個點。第四個點不用遍歷,可以直接查詢是不是在所有的點中出現了即可。

最壞時間複雜度是O(N^3),空間複雜度是O(N)。

class Solution(object):
    def minAreaRect(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        points = map(tuple, points)
        points.sort()
        xdict, ydict = collections.defaultdict(list), collections.defaultdict(list)
        pset = set()
        res = float("inf")
        for point in points:
            xdict[point[0]].append(point)
            ydict[point[1]].append(point)
            pset.add(point)
        for x1 in xdict.keys():
            if len(xdict[x1]) == 1:
                continue
            for i in range(len(xdict[x1]) - 1):
                p1 = xdict[x1][i]
                for j in range(i + 1, len(xdict[x1])):
                    p2 = xdict[x1][j]
                    for p3 in ydict[p1[1]]:
                        if p3 != p1:
                            if (p3[0], p2[1]) in pset:
                                res = min(res, abs((p3[0] - p1[0]) * (p2[1] - p1[1])))
        return res if res != float("inf") else 0

日期

2018 年 11 月 11 日 —— 剁手節快樂