力扣11-盛水最多的容器
本来今天是想学习“贪心算法”,打算找两个题来边学边做。
然后精挑细选选了这题,本来冲着“贪婪”去,瞟一眼题就打算去看题解,然后题解说:最优解是双指针。
啊双指针我会啊,我真蠢😂居然没看出来。然后就写,感觉多简单的
class Solution { public: int maxArea(vector<int>& height) { int maxA = 0; for(int i = 0;i<height.size();i++){ for(int j=i+1;j<height.size();j++){ maxA = max(maxA,(j-i)*min(height[i],height[j])); } } return maxA; } };
再然后就超时了😂时间复杂度达到了O(N2),果然就这么过了它就不配是中等题,肯定是有什么优化的办法。
然后我去看了题解,只有一个双指针解法…所以这跟贪心有什么关系???
题解
官方题解采用的虽然也是双指针,但是不同于我原始的“同向不同初值”,而是采用了“两头往中间靠”的方式。并且根据核心的公式代码
maxA = max(maxA,(j-i)*min(height[i],height[j]));
可以发现,要使乘积最大,即使height[]中的较小值变大乘积才有可能增加;与此同时,(j-i)是注定变小的
……试一试先
class Solution { public: int maxArea(vector<int>& height) { int l = 0, r = height.size()-1; int maxA = 0; while (l <= r) { maxA = max(maxA, (r - l) * min(height[r], height[l])); if (height[l] < height[r]) { ++l; } else { --r; } } return maxA; } };
时间复杂度O(n),遍历一次数组;空间复杂度O(1),但看起来还是很差
那么,为什么这样是正确的,其实每一次移动并不保证乘积一定会变大,但是有这种可能,并且最终结果是包含在这些可能之中,的吧。
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/16147637.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步