盛最多水的容器

image.png
这道题一开始的思路是用两层循环暴力解法,将所有结果列出来然后选最大的。当有这种两层循环暴力解法的想法时,就应该想到可能使用双指针进行优化。

  • 使用双指针关键是:移动哪根针?

本题求的最大容器面积为:两边最小的那边*两边的距离
如果我们移动的是数值大的指针,那么容器面积的参数1不变,两边距离变小;移动数值小的指针,那么容器面积的参数1有变,可能变大或变小,两边距离还是变小,如果是变大那么最大容器面积就会变大。综上,移动小的那边。

  1. class Solution {
  2. public int maxArea(int[] height) {
  3. int left=0;
  4. int right=height.length-1;
  5. int max=0;
  6. while(left<right){
  7. int area=Math.min(height[left],height[right])*(right-left);
  8. max=Math.max(area,max);
  9. if(height[left]<height[right]){
  10. left++;
  11. }else
  12. right--;
  13. }
  14. return max;
  15. }
  16. }

优化

  1. 当移动指针时,下一个指针比当前指针还小,则继续移动,肯定更小所以不需要进行比较。
  2. 当两根指针相等时,可以让两根同时往后/前移动,因为不论其中一根往后/前移动,容器面积是受指向数值小的指针影响。

    1. class Solution {
    2. public int maxArea(int[] height) {
    3. int left=0;
    4. int right=height.length-1;
    5. int max=0;
    6. while(left<right){
    7. int area=Math.min(height[left],height[right])*(right-left);
    8. max=Math.max(area,max);
    9. if(height[left]<height[right]){
    10. //用left++:先取left和right进行判断,然后再通过+1后的left判断
    11. while(left<right&&height[left]<height[left++]){
    12. left++;
    13. }
    14. }else if(height[left]>height[right]){
    15. while(left<right&&height[right]<height[right--]){
    16. right--;
    17. }
    18. }
    19. else
    20. {
    21. ++left;
    22. --right;
    23. }
    24. }
    25. return max;
    26. }
    27. }