LeetCode上做题之体会(二)

一、求一个数的阶乘后面中包含多少个零

题目:Factorial Trailing Zero
Given an integer n, return the number of trailing zeroes in n!.
Note: Your solution should be in logarithmic time complexity.

这道题我找规律找得挺久的,一开始判断错了,直接就以为是5或10的倍数就ok了,之后测试了几次之后发现不是这样的,最后找到规律之后写代码就容易了,我用的是非递归的方法:

    public int trailingZeroes(int n) {
        int z = 0;
        while(n/5 != 0){
            z += n/5;
            n /= 5;
        }
        return z;

下面这个是递归的算法:

    public int trailingZeroes(int n) {
        if(n == 0) return 0;
        return trailingZeroes(n / 5) + n / 5;
    }
二、求最后一个单词的长度

题目:Length of Last Word
Given a string s consists of upper/lower-case alphabets and empty space characters ’ ‘, return the length of last word in the string.
If the last word does not exist, return 0.
Note: A word is defined as a character sequence consists of non-space characters only.
For example,
Given s = “Hello World”,
return 5.

很简单的思路,我们都会想到用拆分函数直接分出最后一个单词,直接计算长度就可以了。

    public int lengthOfLastWord(String s) {
        String[] word = s.split(" ");
        if(word.length == 0) return 0;
        return word[word.length - 1].length();
    }

然而那些厉害的人直接一行代码就解决了:

    return s.trim().length() - s.trim().lastIndexOf(" ") - 1;
三、一道考思维深度的题目

String to Integer
Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.

这道题主要考查的是我们的全面思维能力,因为题目本身给的就很模糊了,很多种情况都可能出现。这就要看答题者考虑得去不全面了。在这里我下面给出的测试用例就是我认为可能会导致程序出现错误的用例,只要这些用例都能够正确,我觉得这个代码提交就没问题的了。

    public int myChange(String str) {
        str = str.trim();
        if(str == null || str.length() == 0) return 0;
        int i = 0, ans = 0, sign = 1, len = str.length();
        if (str.charAt(i) == '-' || str.charAt(i) == '+')
            sign = str.charAt(i++) == '+' ? 1 : -1;
        for (; i < len; i++) {
            int tmp = str.charAt(i) - '0';
            if (tmp < 0 || tmp > 9)
                break;
            if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && Integer.MAX_VALUE % 10 < tmp))
                return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            else
                ans = ans * 10 + tmp;
        }
        return sign * ans;
    }

这里给出一些测试用例,这些用例基本涵盖了所有情况:

testcase:
""          
" "
" 123"
"654 "
" 123 "
" 12 58 "
"+"
"  -12 " 
"-546"
"+ 165"
"+2147483648"
"-2147483649"
"2147483647"
"-2147483648"

我之前也有在其他OJ上做过这种类似题目,也是要分多种情况来考虑一个问题,但是暂时想不起来具体题目是什么了。到时候想到在在这里补充吧。

四、比较两个数的大小

Compare Version numbers
Compare two version numbers version1 and version2.
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.
You may assume that the version strings are non-empty and contain only digits and the . character.
The . character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5 is not “two and a half” or “half way to version three”, it is the fifth second-level revision of the second first-level revision.
Here is an example of version numbers ordering:
0.1 < 1.1 < 1.2 < 13.37

一开始我是采用这种方法直接把字符串改为double,之后用BigDecimal来进行精准比较的,但是提交之后发现,这里面它的测试用例里居然还有包含这种类型(“0.0.1”)的输入之后,我就知道是要用切割的办法来做这道题的了。
所以这个是我的错误代码:

    public int compareVersion(String version1, String version2) {
        double v1 = Double.valueOf(version1).doubleValue();
        double v2 = Double.valueOf(version2).doubleValue();
        BigDecimal ver1 = new BigDecimal(v1);
        BigDecimal ver2 = new BigDecimal(v2);
        if(ver1.compareTo(ver2) > 0) return 1;
        if(ver1.compareTo(ver2) < 0) return -1;
        if(ver1.compareTo(ver2) == 0) return 0;
        return 0;
    }

这个才是最后AC的代码:

    public int compareVersion(String version1, String version2) {
        String[] v1 = version1.split("\\.");
        String[] v2 = version2.split("\\.");
        int l = v1.length > v2.length ? v1.length : v2.length;
        for(int i = 0; i < l; i++){
            int ver1 = i < v1.length ? Integer.parseInt(v1[i]) : 0;
            int ver2 = i < v2.length ? Integer.parseInt(v2[i]) : 0;
            if(ver1 < ver2) return -1;
            if(ver1 > ver2) return 1;
        }
        return 0;
    }

做这道题深深体会到:没有清楚规定输入的题目果然还是需要非常谨慎的啊。

五、反转一个整数

Reverse Integer
  Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321

以下这个是本人自己写的代码,是不是有点冗余而且繁琐啊,看了其他人的简洁代码,才知道是我自己的思路太复杂了。其实按照我的办法就是直接用整数转字符串,再字符串转整数,最后解决所有的特例就OK了。(在这里面少判了几次,之后提交之后才发现错误,才改过来,惨痛教训啊。)

    public int reverse(int x) {
        int tag = 1;
        if(x < 0 && x > Integer.MIN_VALUE) {tag = -1;x = -x;}
        if(x == Integer.MIN_VALUE) return 0;
        String s = "" + x;
        String s1 = "";
        for(int i = s.length() - 1; i >= 0; i--){
            s1 += s.charAt(i);
        }
        if(Long.valueOf(s1) > Integer.MAX_VALUE && tag == 1) 
            return 0;
        if(Long.valueOf(s1) * tag < Integer.MIN_VALUE && tag == -1) 
            return 0;
        return Integer.valueOf(s1) * tag;
    }

这是一个简洁版的代码,思路很简单:

    public int reverse(int x) {
        long result =0;
        while(x != 0)
        {
            result = (result*10) + (x%10);
            if(result > Integer.MAX_VALUE) return 0;
            if(result < Integer.MIN_VALUE) return 0;
            x = x/10;
        }
        return (int)result;
    }

下面给出一些临界测试用例,几乎就涵盖了常错的几个用例了。

    0
    1
    -1213
    10000
    150
    1000000003
    -2147483648
    -1563847412
本系列未完,下一篇请看:LeetCode上做题之体会(三)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值