每日算法练习(2020-1-10)
解法思路,可以使用暴力解法,但是时间复杂度过多,时间复杂度为O(N),所以不建议使用,我采用双指针法,即头尾两个指针,当头指针的值小于尾指针,则头指针后移,否则尾指针后移
代码如下
package com.qyx.Tree; /** * 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。 * 在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。 * 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 说明:你不能倾斜容器,且 n 的值至少为 2。 * @author QYX * */ public class MaxArea { //暴力破解法 //该该空间复杂度为O(1),时间复杂度为O(N^2) public int maxArea01(int[] height) { int maxArea=0; for(int i=0;i<height.length;i++) { for(int j=i+1;j<height.length;j++) { maxArea=Math.max(maxArea,Math.min(height[i], height[j])*(j-i)); } } return maxArea; } //双指针法(double point) /*该空间复杂度为O(1),该时间复杂度为O(N)*/ public int maxArea02(int[] height) { int maxArea=0,l=0,r=height.length-1; while(l<r) { maxArea=Math.max(maxArea, Math.min(height[l],height[r])*(r-l)); if(height[l]<height[r]) { l++; }else{ r--; } } return maxArea; } }
第二题
我采用贪心算法,代码如下
package com.qyx.Tree; import javax.management.relation.Role; /** * 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。 同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况: I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。 * @author QYX * */ public class LuMaNumberTransaction { //使用贪心算法进行整数转罗马数 public String IntTransationLuMaNumber(int num) { String str=""; //1000 100 10 1 500 50 5 char[] romes=new char[]{'M','C','X','I','D','L','V'}; int[] num_split=new int[4]; int count=3; while(count>=0) { //依次计算得出万位,千位,百位及个位,并将其存入数组 num_split[count]=num%10; num=num/10; count--; } for(int i=0;i<4;i++) { switch(num_split[i]) { case 4: str=str+romes[i]+romes[3+i]; break; case 9: str=str+romes[i]+romes[i-1]; break; default: if(num_split[i]<5) { for(int j=0;j<num_split[i];j++) { str=str+romes[i]; } }else{ str=str+romes[3+i]; for(int j=0;j<num_split[i]-5;j++) { str=str+romes[i]; } } } } return str; } public String IntTransactionLuMaNumber02(int num) { //准备接受字符串 String str=""; int count=3; int[] num_split=new int[4]; char[] cs=new char[]{'M','C','X','I','D','L','V'}; while(count>=0) { num_split[count]=num%10; num=num/10; count--; } for(int i=0;i<4;i++) { switch (num_split[i]) { case 4: str=str+cs[i]+cs[3+i]; break; case 9: str=str+cs[i]+cs[i-1]; default: if(num_split[i]<5) { for(int j=0;j<num_split[i];j++) { str=str+cs[i]; } }else{ //先加上5 str=str+cs[3+i]; for(int j=0;j<num_split[i]-5;j++)//因为前面已经加5了,所以这里要减5 { str=str+cs[i]; } } } } return str; } }