剑指 Offer 67. 把字符串转换成整数

题目及例子如上。

本题核心的问题,就是根据字符串str来生成int型数值。比较简便的是从字符串的左边向右边生成:

for (int i = 0; i < str.length(); i++) {
        ans = ans * 10 + str.charAt(i) - '0'; //将对应的'x'转换为实际的x数值
        }

这个核心问题解决之后,关键就是要得到符合我们要求的str,即str全为数字

1.用flag去应对str首字母为+或者-的情况

2.可以用String的trim()函数得到一个去除首尾空格的字符串,不采用这种方式的话可以用循环来实现trim函数的功能,以节省空间。

3.还有一个关键的点是,题目中说明了只能存储32位有符号整数,即存储范围为\[{\rm{[ - }}{{\rm{2}}^{{\rm{31}}}},{2^{31}} - 1]\],即范围是Integer.MIN_VALUE和Integer.MAX_VALUE

因此我们根据str生成数值的时候,要提前一步判断是否溢出。因为每次ans = ans * 10 + str.charAt(i) - '0',即至少是前一个ans * 10,那么我们就可以根据Integer.MAX_VALUE /10 作为一个评判标准,然后根据此时需要加上的str.charAt(i)来判断新生成的ans会不会溢出。

代码一:时间复杂度:O(N),空间复杂度:O(N),运用了trim()函数生成新的字符串

class Solution {
    public int strToInt(String str) {
        if (str == null || str.equals("")) return 0;
        char[] num = str.trim().toCharArray();
        if (num.length == 0) return 0;
        int status = 1, left = 1, ans = 0;
        if (num[0] == '-') {
            status = -1;
        } else if (num[0] != '+') {
            left = 0;
        }
        int check = Integer.MAX_VALUE / 10;
        for (int i = left; i < num.length; i++) {
            if (num[i] < '0' || num[i] > '9') break;
            if (ans > check || (ans == check && num[i] > '7')) return status == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            ans = ans * 10 + num[i] - '0';
        }
        return status * ans;
    }
}

 代码二:将空间复杂度降到了O(1),用循环去实现trim()函数的功能

class Solution {
    public int strToInt(String str) {
        if (str == null || str.equals("")) return 0;
        int left = 0, ans = 0, flag = 1, check = Integer.MAX_VALUE / 10;
        //1.手写一个模块,替代trim(),用来节省O(N)的空间
        while (str.charAt(left) == ' ') {
            left++;
            if (left >= str.length()) return 0; //全为空格
        }
        if (str.charAt(left) == '-') {
            flag = -1;
            left++;
        } else if (str.charAt(left) == '+') {
            left++;
        }
        for (int i = left; i < str.length(); i++) {
            if (str.charAt(i) < '0' || str.charAt(i) > '9') break;
            if (ans > check || (ans == check && str.charAt(i) > '7')) return flag == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            ans = ans * 10 + str.charAt(i) - '0';
        }
        return flag * ans;
    }
}

代码三:没看题解之前我自己想的,在IDEA上面能调试通,leetcode上面提交不过

我的想法是先用两个指针,筛选出只包含纯数字的字符串,然后用这个字符串去生成数值。前面两个代码是边检查字符串同时生成数值

class _67 {
    int left = 0, right = 0, status = 0;

    public int strToInt(String str) {
        str = str.trim();
        if (str == null || str == "") return 0;
        if (str.charAt(0) == '+') {
            left = 1;
            right = loop(left, str);
        } else if (str.charAt(0) == '-') {
            left = 1;
            status = -1;
            right = loop(left, str);
        } else if (str.charAt(0) >= '0' && str.charAt(0) <= '9') {
            right = loop(left, str);
        } else return 0;
        return getAns(str.substring(left, right), status);
    }

    private int loop(int left, String str) {
        int i = 0;
        for (i = left; i < str.length(); i++) {
            if (str.charAt(i) < '0' || str.charAt(i) > '9') break;
        }
        return i;
    }

    private int getAns(String str, int status) {
        double ans = 0;
        for (int i = str.length() - 1; i >= 0; i--) {
            ans += (str.charAt(i) - '0') * Math.pow(10, str.length() - 1 - i);
        }
        if (status == -1) ans = -ans;
        if (ans > Math.pow(2, 31) - 1) return new Double(Math.pow(2, 31) - 1).intValue();
        if (ans < -Math.pow(2, 31)) return new Double(-Math.pow(2, 31)).intValue();
        return new Double(ans).intValue();
    }
}

还有一种思路也是先生成数值之后,再去和区间范围比较,这种方法理论上来说更实用,因为我很难记住每一个边界范围的数值。有时间尝试以下: 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值