LeetCode 11 The container with the most water & 12 integers to Roman numerals

The container with the most water

No public: bigsaireply into the group added punch, pdf reply bigsai get 3GB of resources. Like it and look again , make it a habit!

Title description

Give you n non-negative integers a1, a2,..., an, each of which represents a point (i, ai) in the coordinates. Draw n vertical lines in the coordinates. The two end points of the vertical line i are (i, ai) and (i, 0). Find two of the lines so that the container that they form with the x-axis can hold the most water.

Explanation: You cannot tilt the container, and the value of n is at least 2.

Insert picture description here
Example:

Input: [1,8,6,2,5,4,8,3,7]
Output: 49

analysis

For this problem, the requirement is to find the largest area of ​​the container (ignoring the width). To put it bluntly, it is to find a pair of numbers from a number of numbers, the distance between them and the smaller number is the greatest .

The better the situation is that the number is large (high height) and the distance is long enough! But it is also very likely that the biggest situation is in the middle:
Insert picture description here
Idea 1:
This problem can be solved using a violent method, enumerating all possible situations, we know that each container needs two pillars, and we traverse the pillars every time we let the current pillars Be the shortest and find the longest calculation result. Of course, this result may be on the left or right. So you need to find the farther result that is larger than the current number and compare it with max.

Insert picture description here
In terms of specific implementation, please note that the adjacent distance is 1:

public int maxArea(int[] height) {
    
    

		int max = 0;
		for (int i = 0; i < height.length; i++) {
    
    
			int left = 0, right = 0;
			for (int j = i; j >= 0; j--) {
    
    
				if (height[i] <= height[j]) {
    
    
					left = j;
				}
			}
			for (int j = i; j < height.length; j++) {
    
    
				if (height[i] <= height[j]) {
    
    
					right = j;
				}
			}
			max = Math.max(max, Math.max((i - left) * height[i], (right - i) * height[i]));
		}
		return max;
	}

But the effect is very poor...
Insert picture description here
this method is a method without any progress.

Idea 2:
This question can actually be tested dynamically from the two pointers on both sides. There is no doubt about the initial situation, but next time will the left pointer move to the right or the right pointer move to the left? You have to be clear:

  • Whether moving left or right, the interval between numbers is reduced (distance is reduced)
  • If you move the larger one, the result of the next move must not be greater than this one! (Even if your next one is tall, but according to the shortest one)
  • So every time we move, we move the smaller pointer to the middle, looking for greater possibilities

Insert picture description here

You may be worried. Looking at it from a positional element, it is indeed satisfying. Will it be better if you miss it like this? Of course not. I said that the current situation is the maximum that this short man can reach, which is already a limit. , If you want to break through this limit, you can only find a higher combination.

The implementation code is (see my other optimization ideas for details):

public int maxArea(int[] height) {
    
    
		int max = 0;
		int left = 0;
		int right = height.length - 1;
		int team = 0;
		int len = height.length;
		int leftvalue=0;int rightvalue=0;
		while (len-- > 0) {
    
    
			leftvalue=height[left];rightvalue=height[right];
			if (leftvalue < rightvalue) {
    
    
				team = leftvalue * len;
				if(max<team) {
    
    max=team;}
				left++;
			} else {
    
    
				team = rightvalue * len;
				if(max<team) {
    
    max=team;}
				right--;
			}

		}
		return max;
	}

Good results:
Insert picture description here

Integer to Roman numeral

Title description:

Roman numerals contain the following seven characters: I, V, X, L, C, D and M.
Insert picture description here
For example, the Roman numeral 2 is written as II, which means two parallel ones. 12 is written as XII, which means X + II. 27 is written as XXVII, which is XX + V + II.

Normally, the small numbers in Roman numerals are to the right of the large numbers. But there are special cases, for example, 4 is not written as IIII, but IV. The number 1 is to the left of the number 5, and the number represented is equal to the number 4 obtained by subtracting the number 1 from the large number 5. Similarly, the number 9 is represented as IX. This special rule only applies to the following six situations:

  • I can be placed to the left of V (5) and X (10) to represent 4 and 9.
  • X can be placed to the left of L (50) and C (100) to represent 40 and 90.
  • C can be placed to the left of D (500) and M (1000) to represent 400 and 900.

Given an integer, convert it to a Roman numeral. Ensure that the input is in the range of 1 to 3999.
Insert picture description here

analysis

For this question, it is actually a matter of handling numbers and strings. The rules are very similar to the base conversion , and the ideas are roughly the same-constant division and remainder, but two special cases of 5 and 10 must be considered:

  • For 5 types, the result of the divisor must be 4 and the current content is even digits (0, 2, 4, etc.) (for example, when dealing with 4, 4/1=4, 40/10=4)
  • For 10 types, the result of the divisor is 1, and plus the number one less than it and the number one greater than it (for example, 9/5=1, 9+1=10), all in odd places on.

With the above method, you can find the number corresponding to the position and then you can do it. Remember to superimpose Roman numerals not to use String but StringBuilder .

The implementation code is:

 public static String intToRoman(int num) {
    
    
		 int numvalue []={
    
    1,5,10,50,100,500,1000};
		 char charvalue []= {
    
    'I', 'V', 'X', 'L','C','D','M'};
		 StringBuilder sBuilder=new StringBuilder();
		 int team=0;
		 for(int i=numvalue.length-1;i>=0;i--)
		 {
    
    
			 team=num/numvalue[i];
			 if(team==4&&i%2==0) {
    
    //向上进一为
				 sBuilder.append(charvalue[i]);	
				 sBuilder.append(charvalue[i+1]);	
				 num=num%numvalue[i];
				 
			 }
			 else if (team==1&&i%2==1&&(num+numvalue[i-1])/numvalue[i+1]==1) {
    
    
				sBuilder.append(charvalue[i-1]);
				sBuilder.append(charvalue[i+1]);
				num%=numvalue[i-1];
			}
			 else {
    
    
				for(int j=0;j<team;j++)
				{
    
    
					sBuilder.append(charvalue[i]);
				}
				 num=num%numvalue[i];
			}
			
		 }
		 return sBuilder.toString();	 
	 }

The effect is not bad!
Insert picture description here

Conclusion

This is the end of the introduction of the test questions, of course, if you have other ideas, please also discuss! If you have any questions, please point out!

No public: bigsaireply into the group added punch, pdf reply bigsai get 3GB of resources. I think it’s good. Click a like, double-click a wave! Look forward to having you all the way!

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_40693171/article/details/108148626