leetcode-8-字符串转换整数(atoi)
题目描述:
方法一:正则
import re class Solution: def myAtoi(self, str: str) -> int: INT_MAX = 2149483647 INT_MIN = -2147483648 num = re.findall(r'^[\+\-]?\d+',str.lstrip()) return max(min(int(*num),INT_MAX),INT_MIN)
class Solution: def myAtoi(self, str: str) -> int: return max(min(int(*re.findall('^[\+\-]?\d+', str.lstrip())), 2**31 - 1), -2**31)
java版:
package test; import java.util.regex.Matcher; import java.util.regex.Pattern; class Solution{ public int myAtoi(String str) { str = str.trim(); Pattern p = Pattern.compile("^[\\+\\-]?\\d+"); Matcher m = p.matcher(str); int value = 0; if(m.find()) { try { value = Integer.parseInt(str.substring(m.start(), m.end())); } catch (NumberFormatException e) { value = str.charAt(0) == '-'? Integer.MIN_VALUE:Integer.MAX_VALUE; } } return value; } } public class Test { public static void main(String[] args) { Solution s = new Solution(); System.out.println(s.myAtoi(" -0456")); } }
方法二:
利用双指针加eval()函数
思路:
思路:
用left=0,right标记第一个数字和最后一个数字出现的位置
首先strip()去掉左右的空格
然后判断第一个字符是不是正负号,是的话left置为1
判断left后一个字符是否为数字,不是直接返回0
遍历不断更新right,找到第一个不是数字的字符后break
用res=str[left:right+1]提取纯数字字符串
需要注意的是,可能数字全为0.所以用lstrip()将左边的0清除
最后利用eval()函数将双引号去除,并判断是否需要填正负号
注意一些细节就ok了
下面代码都写有注释,用时28ms时间复杂度o(n)
class Solution: def myAtoi(self, str: str) -> int: str = str.strip() if str == "": return 0 left = 0 right = 0 maxi=2147483647 mini=-2147483648 if str[0]=="+" or str[0]=="-": left = 1 if(left==1 and len(str)==1) or str[left]<"0" or str[right]>"9": return 0 for i in range(left,len(str)): if str[i]>='0' and str[i]<='9': right = i else: break res = str[left:right+1].lstrip("0") if len(res)==0: return 0 else : res=eval(res) if left==1 and str[0]=='-':#判断正负 res=-res if res>maxi: return maxi elif res<mini: return mini else : return res
方法三:自动机
INT_MAX = 2147483647 INT_MIN = -2147483648 class Automaton: def __init__(self): self.state = 'start' self.sign = 1 self.ans = 0 self.table = { 'start':['start','signed','in_number','end'], 'signed': ['end', 'end', 'in_number', 'end'], 'in_number': ['end', 'end', 'in_number', 'end'], 'end': ['end', 'end', 'end', 'end'], } def get_col(self,c): if c.isspace(): return 0 if c == '+' or c == '-': return 1 if c.isdigit(): return 2 return 3 def get(self,c): self.state = self.table[self.state][self.get_col(c)] if self.state == 'in_number': self.ans = self.ans*10 + int(c) self.ans = min(self.ans,INT_MAX) if self.sign == 1 else min(self.ans,-INT_MIN) elif self.state == 'signed': self.sign = 1 if c == '+' else -1 class Solution: def myAtoi(self, str: str) -> int: automaton = Automaton() for c in str: automaton.get(c) return automaton.sign * automaton.a
java版
class Solution { class Automaton { final String START = "start"; final String SIGNED = "signed"; final String IN_NUM = "in_number"; final String END = "end"; String state = START; Map<String, String[]> map; public int sign = 1; public long ans = 0; public Automaton() { map = new HashMap<>(); map.put(START, new String[]{START, SIGNED, IN_NUM, END}); map.put(SIGNED, new String[]{END, END, IN_NUM, END}); map.put(IN_NUM, new String[]{END, END, IN_NUM, END}); map.put(END, new String[]{END, END, END, END}); } public int get_col(char c) { if (c == ' ') return 0; if (c == '+' || c == '-') return 1; if (c >= '0' && c <= '9') return 2; return 3; } public void get(char c) { state = map.get(state)[get_col(c)]; if (state.equals(IN_NUM)) { ans = ans * 10 + c - '0'; if (sign == 1) { ans = Math.min(ans, Integer.MAX_VALUE); } else { // -(long)Integer.MIN_VALUE,这个操作有点东西,不然越界 ans = Math.min(ans, -(long)Integer.MIN_VALUE); } } else if (state.equals(SIGNED)) sign = c == '+' ? 1 : -1; } } public int myAtoi(String str) { Automaton automaton = new Automaton(); char[] c = str.toCharArray(); for (char ch : c) { automaton.get(ch); } return automaton.sign * ((int) automaton.ans); } }