[34]四数相加 II 和 盛最多水的容器

[34]四数相加 II 和 盛最多水的容器

四数相加 II

题目要求

给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

思路

哈希表查询,把4个数组的问题拆分为两个,这样循环的复杂度会低一些。

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        #countAB = collections.Counter(u + v for u in A for v in B)
        count = 0
        hashMap = {}

        for i in range(len(nums1)):
            for j in range(len(nums2)):
                if not nums1[i] + nums2[j] in hashMap:
                    hashMap[nums1[i] + nums2[j]] = 1
                else:
                    hashMap[nums1[i] + nums2[j]] = hashMap[nums1[i] + nums2[j]] + 1
        
        for i in range(len(nums3)):
            for j in range(len(nums4)):
                if (-(nums3[i] + nums4[j])) in hashMap:
                    count = count + hashMap[-(nums3[i] + nums4[j])]
                
        return count

盛最多水的容器

题目要求

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器

示例 1:
​​​​
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

思路

用一个双循环来找到最大的面积,理论上来说是可行的,但是会超时。。。

考虑第一步,假设当前左指针和右指针指向的数分别为 x x x y y y,不失一般性,我们假设 x ≤ y x \leq y xy。同时,两个指针之间的距离为 t t t。那么,它们组成的容器的容量为:

m i n ⁡ ( x , y ) ∗ t = x ∗ t min⁡(x,y)\ast t=x\ast t min(x,y)t=xt
我们可以断定,如果我们保持左指针的位置不变,那么无论右指针在哪里,这个容器的容量都不会超过 x ∗ t x\ast t xt。注意这里右指针只能向左移动,因为 我们考虑的是第一步,也就是 指针还指向数组的左右边界的时候

我们任意向左移动右指针,指向的数为 y 1 y_1 y1,两个指针之间的距离为 t 1 t_1 t1,那么显然有 t 1 < t t_1<t t1<t,并且 m i n ⁡ ( x , y 1 ) ≤ m i n ⁡ ( x , y ) min⁡(x,y_1) \leq min⁡(x,y) min(x,y1)min(x,y)

如果 y 1 ≤ y y_1\leq y y1y,那么 m i n ⁡ ( x , y 1 ) ≤ m i n ⁡ ( x , y ) min⁡(x,y_1)\leq min⁡(x,y) min(x,y1)min(x,y)

如果 y 1 > y y1>y y1>y,那么 m i n ⁡ ( x , y 1 ) = x = m i n ⁡ ( x , y ) min⁡(x,y_1)=x=min⁡(x,y) min(x,y1)=x=min(x,y)

因此有:

m i n ⁡ ( x , y t ) ∗ t 1 < m i n ⁡ ( x , y ) ∗ t min⁡(x,y_t)\ast t_1<min⁡(x,y)\ast t min(x,yt)t1<min(x,y)t
即无论我们怎么移动右指针,得到的容器的容量都小于移动前容器的容量。也就是说,这个左指针对应的数不会作为容器的边界了,那么我们就可以丢弃这个位置,将左指针向右移动一个位置,此时新的左指针于原先的右指针之间的左右位置,才可能会作为容器的边界。

class Solution:
    def maxArea(self, height: List[int]) -> int:

        maxArea = 0
        left = 0
        right = len(height) - 1
        while left < right:
            area = (right - left) * min(height[right], height[left])
            if maxArea < area:
                maxArea = area

            if height[left] > height[right]:
                right = right - 1
            else:
                left = left + 1    

        return maxArea
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值