8. 字符串转整数 (atoi) 题目说明

本文详细解析了LeetCode第八题的解题思路及代码实现,包括去除空格、符号判断、数字转换等关键步骤,并提供了两种不同的解决方案。


开始刷LeetCode题,这个是第八题。

有这么几个问题需要注意:
1.怎么判断超出范围:一开始我是用的取出整个完整整数字符串之后用Long存,如果比最大Int大/小,就输出最大/小值,但是这样不好,如果比Long大呢?所以,后来开始用计算的,用一个long,当计算出比极值大或者小时候,就返回极值了。

2.charAt函数,确实是可以取一个char 值为 ‘ ’ (有空格),而不能用char=‘’(没有空格)。
3.我的思路是这样:

判断是否空,或者只有字符,或者第一个非空是字符等等
取出包含数字的一个子字符串,而且最后一位是第一次发现的数字的最后一个数字,前后没有空格,然后继续判断。比如:
“    -=asd123   12w”取出来之后是“-=asd123”

再判断是否为空,然后判断第一位是不是只有字符,如果第一位是符号,且第二位如果不是数字,要return 0,另外就是注意可能值有一位数的情况。所以判断条件都要加限制,下标小于长度。
如果第二位(有的话)不是数字,肯定return。

代码如下,但是这个效率很低,所以我需要再分析好的答案:
class Solution {
    public int myAtoi(String str) {
        if(str.equals("")||str.equals("+")||str.equals("-")){
            return 0;
        }
        String result="";
        int n=0;
        while(n<str.length()&&str.charAt(n)==' '){
            n++;
        }
        if(n>=str.length()){
            return 0;
        }
        boolean findNum=false;
        boolean keep=true;
        for(int i=n;i<str.length();i++){
            if(keep){
                if(findNum&&(!isInt(str.charAt(i)))){
                    keep=false;
                    break;
                }
                if(isInt(str.charAt(i))){
                    findNum=true;
                }
            }else{
                break;
            }
            result+=str.charAt(i);
        }
       
        if((!isInt(result.charAt(0)))&&(!ifSym(result.charAt(0)))){
            return 0;
        } 
        if(result.length()>2&&(!isInt(result.charAt(1)))){
            return 0;
        }
        int symb=1;
        int ans=0;
        if(ifSym(result.charAt(0))){
            symb=isSym(result.charAt(0)) ;
            ans = cal(result,1,symb);
        }else{
            ans =cal(result, 0,symb);
        }
        return ans;       
    }
    public boolean isInt(char c){
        if(c>='0'&&c<='9'){
            return true;
        }else{
            return false;
        }
    }
    public boolean ifSym(char c){
        if(c=='+'|| c=='-'){
            return true;
        }else{
            return false;
        }
    }
    public int isSym(char c){
        if(c=='+'){
            return 1;
        }else if(c=='-'){
            return -1;
        }else{
            return 0;
        }
    }
    public int cal(String s,int start,int flag){
        long ans=0;
        for(int i=start;i<s.length();i++){
              if(flag<0){
                ans=ans*10+flag*Integer.parseInt(String.valueOf(s.charAt(i)));
            }else{
                ans=ans*10+Integer.parseInt(String.valueOf(s.charAt(i)));
            }
            if(ans>=Integer.MAX_VALUE){
                return Integer.MAX_VALUE;
            }else if(ans<=Integer.MIN_VALUE){
                return Integer.MIN_VALUE;
            }
        }
        return (int)ans;
       
    }
}
关于好的答案,分析如下:

字符转换数字的一个方式:
数字+字符-48(或者‘0’,48是0的ASC码)

例如
3+‘4’-‘0’=7

但是,如果两个都是字符,例如'4'+'4',的出来的结果是104,就是ASC码相加,所以,第一个要是数字。
好的算法的思路是这样:

只需要去掉首尾空格,符号记录,有数字就累加,如果不是数字,就break。
有一个技巧很有意思,就是for里面执行一次,然后在一个for把后续完成,很适合这里,因为第一次验证符号等等必须做,然后继续计算:

for(int i=0;i<s.length();i++){
.........
        i++;
    for(;i<s.length();i++){
}
break;

补充一下重写的,这个效率高得多:

class Solution {
    public int myAtoi(String str) {
        str=str.trim();
        long result=0;
        int symb=1;
        char[] chr=str.toCharArray();
        for(int i=0;i<str.length();i++){
            if(chr[i]=='-'){
                symb=-1;
            }else if(chr[i]=='+'){
                
            }else if(chr[i]>='0'&&chr[i]<='9'){
                result=result*10+chr[i]-'0';
            }else{
                break;
            }
            i++;
            for(;i<str.length();i++){
                if(chr[i]>='0'&&chr[i]<='9'){
                    result=result*10+chr[i]-48;
                    if(result>Integer.MAX_VALUE){
                        break;
                    }
                }else{
                    break;
                }
            }
            break;       
        }
        result=result*symb;
        if(result>Integer.MAX_VALUE){
            return Integer.MAX_VALUE;
        }else if(result<Integer.MIN_VALUE){
            return Integer.MIN_VALUE;
        }else{
            return (int)result;
        }
    }
}

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值