刷题日记--leetcode篇(Java)

1、盛最多水的容器(11题)

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

(1)解法1:枚举法,一个指针从0到(height.length-1),一个指针从(height.length-1)到0,记录每次的值并比较,最后返回最大值;

class Solution {
    public int maxArea(int[] height) {
        int n = height.length, num = 0, max = 0;
        for(int i = 0; i < n; i++){
            for(int j = n-1; j >= 0; j--){
                if(height[i] < height[j]){
                    num = height[i] * ( j - i );
                }
                else{
                    num = height[j] * ( j - i );
                }
                if(num > max)
                max = num;
            }
        }
        return max;
    }
}

(2)解法2:从数组两端开始,每次移动高度较小的指针,这样可以保证容器的宽度在减小,而要获得更大的面积只有在高度更高的情况下。因此移动指针时,每次选择高度较小的指针。(很巧妙的思想,代码也差不多)。

class Solution {
    public int maxArea(int[] height) {
        int n = height.length;
        int max = 0;
        int left = 0;
        int right = n - 1;
        
        while (left < right) {
            int minHeight = Math.min(height[left], height[right]);
            max = Math.max(max, minHeight * (right - left));
            
            if (height[left] < height[right]) {
                left++;
            } else {
                right--;
            }
        }
        
        return max;
    }
}

2、罗马数字转整数(17题)

罗马数字包含以下七种字符: I, V, X, LCD 和 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。

给定一个罗马数字,将其转换成整数。

解法:这道题很简单,不要被罗马数字这一大段问题描述给吓到了。其实总的来说就是一个累计和的问题,但是有三种特殊情况,即'L',  'X', 'C'。当这三个字符处于比他大的数字左边的时候,即减去该数字。那么确定该数字左边,即字符串下一个字符是啥再对该字符做加或减的操作即可。

有更好的方法可以评论在下面噢~

class Solution {
    public int romanToInt(String s) {
        int sum = 0;
        int len = s.length();
        for(int i = 0; i < len ;i++ ){
            char value = s.charAt(i);
            if(value=='V'){
                sum += 5;
            }
            else if(value=='L'){
                sum += 50;
            }
            else if(value=='D'){
                sum += 500;
            }
            else if(value=='M'){
                sum += 1000;
            }
            else if(value=='I'){

               if( i+1 < len && (s.charAt(i+1)=='V'||s.charAt(i+1)=='X')){
                sum -= 1;
               }else{
                sum += 1;
               }
            }

            else if(value=='X'){
               if(i+1 < len && (s.charAt(i+1)=='L'||s.charAt(i+1)=='C')){
                sum -= 10;
               }else{
                sum += 10;
               }
            }

            else if(value=='C'){
                if(i+1 < len && (s.charAt(i+1)=='D'||s.charAt(i+1)=='M')){
                sum -= 100;
               }else{
                sum += 100;
               }
            }
        }

        return sum;
    }
}

3、最长公共前缀(14题)

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

解法:将字符串数组中的第一个字符串看作是最长公共前缀,然后将后面的每一个字符串依次和它比较,这里我投机取巧使用了startsWith()方法,这个方法一般用于检测字符串是否以指定的前缀开始的。当字符串与前缀不匹配时,不断缩短前缀直到匹配为止。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0) {
            return "";
        }

        String prefix = strs[0];
        
        for (int i = 1; i < strs.length; i++) {
            // 当前字符串与前缀不匹配时,不断缩短前缀直到匹配为止
            while (!strs[i].startsWith(prefix)) {
                prefix = prefix.substring(0, prefix.length() - 1);
                if (prefix.isEmpty()) {
                    return "";
                }
            }
        }
        return prefix;
    }
}

4、

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值