构造矩形

标签: 数学

难度: Easy

作为一位web开发者, 懂得怎样去规划一个页面的尺寸是很重要的。 所以,现给定一个具体的矩形页面面积,你的任务是设计一个长度为 L 和宽度为 W 且满足以下要求的矩形的页面。要求:

  1. 你设计的矩形页面必须等于给定的目标面积。
  2. 宽度 W 不应大于长度 L ,换言之,要求 L >= W
  3. 长度 L 和宽度 W 之间的差距应当尽可能小。

返回一个 数组 [L, W],其中 LW 是你按照顺序设计的网页的长度和宽度
 

示例1:

输入: 4
输出: [2, 2]
解释: 目标面积是 4, 所有可能的构造方案有 [1,4], [2,2], [4,1]。
但是根据要求2,[1,4] 不符合要求; 根据要求3,[2,2] 比 [4,1] 更能符合要求. 所以输出长度 L 为 2, 宽度 W 为 2。

示例 2:

输入: area = 37
输出: [37,1]

示例 3:

输入: area = 122122
输出: [427,286]

提示:

  • 1 <= area <= 107

Submission

运行时间: 35 ms

内存: 15.9 MB

class Solution:
    def constructRectangle(self, area: int) -> List[int]:
        mid = int(area ** 0.5)
        while area % mid:
            mid -= 1

        return [area // mid, mid]

Explain

该题解的思路是从 area 的平方根开始,逐渐递减找到可以整除 area 的因子。这样可以保证找到的两个因子之差是最小的,且第一个因子大于等于第二个因子。

时间复杂度: O(sqrt(n))

空间复杂度: O(1)

class Solution:
    def constructRectangle(self, area: int) -> List[int]:
        # 从 area 的平方根开始寻找可整除 area 的因子
        mid = int(area ** 0.5)
        
        # 逐渐递减 mid,直到找到可整除 area 的因子
        while area % mid:
            mid -= 1
        
        # 返回 [长度, 宽度],长度大于等于宽度
        return [area // mid, mid]

Explore

从area的平方根开始查找因子是因为平方根是因子对称性的分界线。如果area可以被某个数x整除,那么相应的另一个因子y可以表示为area/x。当x小于或等于area的平方根时,y将会大于或等于平方根。这意味着,只需要检查到平方根即可找到所有可能的因子对,这样可以大大减少需要检查的因子数量,提高效率。

选择递减mid的方式是为了尽快找到长度和宽度差距较小的因子对。从平方根向下递减查找因子,可以较快地找到较为接近的两个因子,这样得到的矩形长度和宽度差距较小,更接近于理想的接近正方形的矩形。如果从1递增到sqrt(area),虽然也能找到因子对,但首先找到的因子对差距较大,不符合题目要求的优化目标。

当从平方根递减查找因子时,首先找到的因子对(L, W)将是在满足L>=W的条件下,L和W相差最小的。因为从平方根开始递减意味着找到的第一个因子L将尽可能接近于sqrt(area),而对应的W = area / L也接近于sqrt(area)。这样,L和W相差最小,从而使得矩形的形状更加接近正方形。

当area为质数时,除了1和area本身外,没有其他因子。这种情况下,算法的效率会降低,因为必须从sqrt(area)递减到1,直到最后检查到因子1。因此,对于质数的area,这个方法会进行较多的迭代,这是算法效率的一个极端情况。然而,在实际情况中,这种情况并不频繁,因此算法整体上仍然具有较好的效率和实用性。