(Python)LeetCode 11:盛最多水的容器

题目:

思路:

这道题目我一开始写错了两次,第一次是本身代码逻辑少了一部分,主要是因为列表的复制这里使用错误,第二次代码应该是正确的,但是还是我一直容易忽略的问题,代码的效率,运行超出了时间限制。对这两种情况的思路都做一个总结,可以参考一下。

效率低下的一种:

        这个我主要是这么想的,先把列表排个序,从大到小,然后分别找到当前最大的两个元素的下标,然后计算面积,然后第二次找的时候,原本第二大的数变成现在最大的数,再找到第三大的数(也就是排序后的第三个数作为第二大的数),在作为目前最大的两个数,以比较小的作为高,两者下标的差值作为底来计算面积,但是这里有一个需要注意的,列表中是可能会有重复的数的,那么他们的下标查找就会重复,如果不考虑这个可能会出现问题,所以,还需要另外一个列表来记录哪些元素已经被“使用”过了,用过的那个下标就不能再用了,,所以这里就有一个比较麻烦的就是另外这个标记的元素。最后我用了两个列表来解决这个问题,并且其中涉及到了列表的复制,不能直接fill2 = fill1,这样的话实际上相当于是把地址复制了,不论是对fill1操作还是fill2操作都是对同一块内存操作,所以要用 list.copy()

附上代码一:

class Solution:
    def maxArea(self, height: List[int]) -> int:
        count = 0   # 统计列表元素个数
        fill1 = []  
        fill2 = []
        for i in height:
            count+=1
            fill1.append(0)
            fill2.append(0)
        sortList = sorted(height,reverse=True)  # 对列表排序 降序
        i = 0
        Area = 0  # 面积
        while i < count:
            first = sortList[i]  # 查找最大的元素
            first_index = height.index(first) # 最大元素的下标
            while fill1[first_index] != 0:
                if first_index < count:  # 判断是否已经被找过,如果找过则标记为1,没有则是0
                    first_index = height.index(first,first_index+1)  # 从下一个位置开始找
            fill1[first_index] = 1   # 将下标标记为1,避免有同样的数每次找的都是同一个
            fill2 = fill1.copy()  # 复制内容,不能用fill2=fill1

            j = i + 1 # j从i的下一个开始,减少查找次数
            while j < count:
                second = sortList[j]   # 查找第二大的元素
                second_index = height.index(second)  # 下标
                while fill2[second_index]!=0:
                    if second_index < count:  # 判断是否该位置被找到过
                        second_index = height.index(second,second_index+1)
                    else:
                        break
                fill2[second_index] = 1
                V = abs(second_index - first_index) * second
                if V > Area:
                    Area = V
                j += 1
            i += 1
        return Area

第二种方法要简单许多:

        最开始最大的底是整一个列表的底,那么此时的面积就是这个底乘上第一个和最后一个元素较小的那个值(作为高),也就是需要两个指针,然后计算完之后,移动其中指针,此时由于指针移动了,也就是底肯定是变小了,所以高应该要变大才会使得面积变大,所以要移动比较小的那个指针,然后计算面积,看是否比原来的大,以此循环找到最大的面积。

附上代码二:

class Solution:
    def maxArea(self, height: List[int]) -> int:
        count = 0
        for i in height:
            count += 1
        Area = 0
        first = 0
        last = count-1
        bottom = count-1
        while first<last:
            if height[first] <= height[last]:
                S = bottom * height[first]
                if S > Area:
                    Area = S
                first+=1
            else:
                S = bottom * height[last]
                if S > Area:
                    Area = S
                last-=1
            bottom -= 1
        return Area

这个方法明显简单许多,,但是不知道为啥一开始没想到,所以在代码的效率方面还有很多的路要走。。。。

结果:

 关于LeetCode的方法欢迎大家一起讨论~

如果觉得有兴趣的可以关注我~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值