给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
分析: 这题一开始想用暴力直接算出来,也就是时间复杂度O(N^2)的方法,结果最后一场超长数组的测试用例直接没通过,超时了QAQ。但我觉得在实际面试的时候,如果一时想不到太好的办法,直接暴力也不是一个坏的办法。下面附个暴力解法:
func maxArea(height []int) int {
var maxArea int = 0
var tempArea int = 0
if len(height) <= 1 {
return 0
}
for i := 1; i <= len(height); i++ {
for j := i+1; j <= len(height); j++ {
if height[j-1] < height[i-1] {
tempArea = height[j-1]*(j-i)
} else {
tempArea = height[i-1]*(j-i)
}
if tempArea > maxArea {
maxArea = tempArea
}
}
}
return maxArea
}
当然啦,正经人谁用暴力解法嘛!这题应该还是用双指针的解法。一个指向数组第一个数,一个指向数组最后一个数,求出面积后,再移动比较小的一端,之所以要移动高度小的一端指针,是因为这个面积是由两边高度矮的一方决定的(木桶效应嘿嘿嘿?)所以,如果移动高的一端指针,并不会使得面积变大,而且由于宽的减少,面积只会减少,因此我们不断移动矮的一端的指针,直至指针相遇。附代码:
func maxArea(height []int) int {
i, j := 0, len(height) - 1
m := 0
for i < j {
// 计算当前最大面积
cur := (j - i) * min(height[i], height[j])
if cur > m {
m = cur
}
// 移动较小的一侧指针
if (height[i] < height[j]) {
i++
} else {
j--
}
}
return m
}
func min(x, y int) int {
if x > y {
return y
}
return x
}