[Data structure and algorithm] The algorithm that the container holds the most water

You give a non-negative integer n A . 1 , A 2 , ..., A n , a number of representatives of each point coordinates (I, A I ). Draw n vertical lines in the coordinates. The two end points of the vertical line i are (i, a i ) and (i, 0). Find two of the lines so that the container that they form with the x-axis can hold the most water.
Note: The container cannot be tilted, and the value of n is at least 2.

1. Subject requirements

Insert picture description here

  • The vertical line in the figure represents the input array [1, 8, 6, 2, 5, 4, 8, 3, 7]. In this case, the maximum value that the container can hold water (shown as the blue part) is 49.
  • Example
	输入:[1,8,6,2,5,4,8,3,7]
	输出:49
Two, algorithm example
  • Siwft example:
    • Through the meaning of the question, the height of the water is determined by the minimum value of the interval, and the volume of the water is determined by the height and width. Therefore, we continue to indent both sides of the interval, find the solution of each interval, and record the largest of them.
    • In the initial state, select the leftmost and rightmost pillar, and then move the short pillar to the middle. At each step of the operation, the volume of water that can be contained is calculated.
    • The Swift algorithm is as follows:
	class Solution {
    
    
	    func maxArea(_ height: [Int]) -> Int {
    
    
	      
	      var left = 0
	      var right = height.count-1
	      var maxAns = 0
	      var per = 0
	    
	      while left < right {
    
    
	        per = min(height[left], height[right]) * (right-left)
	        maxAns = max(maxAns, per)
	        if height[left] <= height[right] {
    
    
	          // 优先剔除矮木板
	          left += 1
	        } else {
    
    
	          right -= 1
	        }
	      }
	      return maxAns
	    }
	}
  • Java example:
    • Algorithm flow: Set the double pointers i and j at both ends of the container wall respectively, move the pointers according to the rules (following instructions), and update the maximum area res until i == j and return res.

    • Pointer movement rules and proofs: Each time the short board in the height h[i], h[j] of the two boards surrounding the water tank is selected, narrow one grid to the middle. The following proof:

      • Suppose the area of ​​the water tank in each state is S(i,j), (0 <= i <j <n). Since the actual height of the water tank is determined by the short board of the two plates, the area formula S(i,j ) = min(h[i],h[j]) × (j−i).
      • In each state, whether the long board or the short board is narrowed by 1 grid, it will cause the bottom width of the sink −1:
        • If you move the short plate inward, the short plate min(h[i],h[j]) of the water tank may become larger, so the area of ​​the water tank S(i,j) may increase.
        • If you move the long board inward, the short board min(h[i],h[j]) of the sink remains unchanged or becomes smaller, and the area of ​​the next sink must be smaller than the area of ​​the current sink.
    • Therefore, narrowing the short board inward can obtain the maximum area. To understand from another perspective:

      • If no movement rules are specified, the number of states of S(i,j) in all movements is C(n,2), that is, all states are enumerated by force.
      • In the state S(i,j), move the short board inward to S(i+1,j) (assuming h[i]<h[j] ), it is equivalent to eliminating S(i,j−1), S(i,j−2),...,S(i,i+1) state set. And the area of ​​all eliminated states must be <=S(i,j):
        • Short board height: the same or shorter than S(i,j) (<=h[i]);
        • Bottom width: shorter than S(i,j).
      • Therefore, the area of ​​all eliminated states is <S(i,j). In layman's terms, every time we move the short board inward, all the elimination states will not cause the loss of the maximum area.
    • Complexity analysis:

      • The time complexity is O(N), and the double pointer traverses the bottom width N once.
      • The space complexity is O(1), and the pointer uses a constant extra space.
    • The Java algorithm is as follows:

	class Solution {
    
    
	    public int maxArea(int[] height) {
    
    
	        int i = 0, j = height.length - 1, res = 0;
	        while(i < j){
    
    
	            res = height[i] < height[j] ? 
	                Math.max(res, (j - i) * height[i++]): 
	                Math.max(res, (j - i) * height[j--]); 
	        }
	        return res;
	    }
	}

Guess you like

Origin blog.csdn.net/Forever_wj/article/details/108715016