Container With Most Water和3Sum

〇、11. Container With Most Water 描述

Given n non-negative integers a1a2, ..., an , where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container and n is at least 2.

大意:给了你柱子的高度,你得找出哪两根柱子之间的面积最大

 

 

 

11. Container With Most Water  思路

1、暴力解:O(n²)的方法,每根柱子和其他的匹配,遍历完毕,找到最大。

2、两头逼近:

既然是求最大面积,我们当然想高尽量大、宽也尽量大

从上图可以看出,依次找出两根最高、最高的与次高.....最终也会变成O(n²)的方法;

所以我们从'宽'入手,首先找距离最远的两根(即下标为0,和下标最后),选择矮的柱子为高,计算并记录面积;

然后两根柱子中,我们保留高的那一根,矮的一边则向中间逼近,直到两柱子相遇...并在此过程中比较得出最大值;

在选择最远距离->宽尽量大,保留高的一方->高尽量大。

 1 class Solution(object):
 2     def maxArea(self, height):
 3         length = len(height)
 4         i = 0
 5         j = length-1
 6         max = 0
 7         while i<j :
 8             if height[i]>height[j] :
 9                 max = height[j]*(j-i) if max<height[j]*(j-i) else max
10                 j -=1
11             else:
12                 max = height[i] * (j - i) if max < height[i] * (j - i) else max
13                 i += 1
14         return max

 

一、15. 3Sum 描述

Given an array nums of n integers, are there elements abc in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Notice that the solution set must not contain duplicate triplets.

example:
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]

大意:给出一连串的整数,找出其中加起来等于0的三个元素(可能有0组或多组,且不能重复)

 

15. 3Sum 思路

我们可以固定一个元素,然后找其它两个元素,即  -a = b + c,这样就可以和11. Container With Most Water  差不多,采用两头(i,j)逼近方法。

但困难的地方在于  不能重复(像例子中,虽然有两个-1,但结果不能有两个[-1, 0, 1],要保证组与组的数值不能完全同样);

解决办法是跳过 已经判断的、重复的 元素;

小细节:三个元素和为0,所以其中要么正负搭配,要么全为0,可以将数组先排序,到固定位为正数时,迭代便可停止。

 

 

 

 1 class Solution(object):
 2 
 3     def threeSum(self, nums):
 4         nums.sort()
 5         result = []
 6         for start in range(len(nums)):
 7 
 8             if start > 0 and nums[start] == nums[start-1]:    # 跳过重复的固定位
 9                 continue
10 
11             i = start+1
12             j = len(nums)-1
13             oneSum = -nums[start]
14 
15             while i < j and nums[start] <= 0:
16                 twoSum = nums[i] + nums[j]
17                 if twoSum > oneSum:
18                     j -= 1
19                 elif twoSum < oneSum:
20                     i += 1
21                 else:
22                     temp = [nums[start], nums[i], nums[j]]
23                     result.append(temp)
24                     while i < j and nums[i] == nums[i+1]:    # 跳过重复的,已判断的i
25                         i += 1
26                     while i < j and nums[j] == nums[j-1]:       # 跳过重复的,已判断的j
27                         j -= 1
28                     i += 1
29                     j -= 1
30         return result

 

posted @ 2020-09-15 09:18  Drajun  阅读(162)  评论(0编辑  收藏  举报