1.题目
https://leetcode-cn.com/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/
2.分析
数字越界处理
在每轮拼接前,判断res拼接后是否超过2147483647,若超过则加上符号位直接返回。
两种越界情况:
越界
res>int_max/10
res_next=res*10+x=(int_max/10)10+x=21474836410+x=2147483640+x>2147483647,即x>7时
3.代码
3.0 更新:简洁易懂
/*
边界判断方法
*/
if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && (currChar - '0') > Integer.MAX_VALUE % 10)) {
return Integer.MAX_VALUE;
}
if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && (currChar - '0') > -(Integer.MIN_VALUE % 10))) {
return Integer.MIN_VALUE;
}
class Solution {
public int myAtoi(String s) {
int len=s.length();
int res=0;
int sign=1;
int index=0;
while(index<len&&s.charAt(index)==' '){//去除 前导空格
index++;
}
if(index==len){//结束了,直接返回
return 0;
}
if(s.charAt(index)=='+'){
index++;
}
else if(s.charAt(index)=='-'){
sign=-1;
index++;
}
while(index<len){
if(s.charAt(index)<'0'||s.charAt(index)>'9'){//不是数字结束
break;
}
int cur=s.charAt(index)-'0';//当前数字
int tmp=res*10+cur;
if(tmp/10!=res){//越界了
if(sign>0){
return Integer.MAX_VALUE;
}
else{
return Integer.MIN_VALUE;
}
}
else{
res=tmp;
}
index++;
}
return sign*res;
}
}
3.1 空间复杂度O(N)的代码
代码
class Solution {
public int strToInt(String str) {
//字符串为空,返回0
if(str==null)
return 0;
//删除首尾空格
char[] cs=str.trim().toCharArray();
//字符串为空,返回0
if(cs.length==0)
return 0;
//cs[0],判断符号
int sign=0;
if(cs[0]=='+')
sign=1;
if(cs[0]=='-')
sign=-1;
//cs[0]不是数字也不是正负号,返回0
if(sign==0&&(cs[0]<'0'||cs[0]>'9'))
return 0;
int res=0;
int bi=Integer.MAX_VALUE/10;
int x;
int j=(sign==0?0:1);
//cs[0]为数字,从0开始;cs[0]为正负号,从1开始
for(int i=j;i<cs.length;i++){
if(cs[i]<'0'||cs[i]>'9')
break;
x=(int)(cs[i]-'0');
if((res>bi)||((res==bi)&&(x>7))){
return sign==-1?Integer.MIN_VALUE:Integer.MAX_VALUE;
}
res=res*10+x;
}
if(sign!=-1)
sign=1;
return sign*res;
}
}
复杂度
时间复杂度 O(N) : 其中 N为字符串长度,线性遍历字符串占用 O(N) 时间。
空间复杂度 O(N): 删除首尾空格后需建立新字符串,最差情况下占用O(N) 额外空间。
结果
3.2 空间复杂度O(1)的代码
代码
class Solution {
public int strToInt(String str) {
int res = 0, bndry = Integer.MAX_VALUE / 10;
int i = 0, sign = 1, length = str.length();
if(length == 0) return 0;
//不用trim删除空格
while(str.charAt(i) == ' ')
if(++i == length) return 0;
//此时 i 就是第一个非空字符的下标
if(str.charAt(i) == '-') sign = -1;
if(str.charAt(i) == '-' || str.charAt(i) == '+') i++;
for(int j = i; j < length; j++) {
if(str.charAt(j) < '0' || str.charAt(j) > '9') break;
if(res > bndry || res == bndry && str.charAt(j) > '7')
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
res = res * 10 + (str.charAt(j) - '0');
}
return sign * res;
}
}
复杂度
时间复杂度O(N)
空间复杂度O(1)
结果
×之前自己写的过不了代码
class Solution {
public int strToInt(String str) {
//去除字符串开头的空格
str=str.trim();
//字符串为空,不需要转换
if(str==null)
return 0;
//first是字符串的第一个字符
char first=str.charAt(0);
//第一个是否为正负号
int k=0;
if(first=='-')
k=-1;
if(first=='+')
k=1;
//如果第一个不是数字,返回0
if(k==0&&!Character.isDigit(first))
return 0;
ArrayList<Integer> list=new ArrayList<>();
list.add((int)first-(int)('0'));
for(int i=1;i<str.length();i++){
//不是数字,退出循环
if(!Character.isDigit(str.charAt(i)))
break;
//计算当前字符对应的数字值
int num = (int)(str.charAt(i)) - (int)('0');
list.add(num);
}
//生成结果
long result=0;
int size=list.size();
int flag=1;
//从最后一位开始
for(int i=size-1;i>=1;i--){
result+=flag*list.get(i);
flag=flag*10;
}
if(k==0){
result+=list.get(0)*flag;
}
else if(k==-1){
result=-result;
}
else{
//+,不变
}
if(result>Integer.MAX_VALUE){
return Integer.MAX_VALUE;
}
if(result<Integer.MIN_VALUE){
return Integer.MIN_VALUE;
}
return (int)result;
}
}