LeetCode Edge Lord
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 class Solution { public int myAtoi (String s) { if (s.length() == 0 ) return 0 ; int pos = 0 ; while (pos < s.length() && s.charAt(pos) == ' ' ) pos += 1 ; if (pos == s.length()) return 0 ; boolean isPositive; if (Character.isDigit(s.charAt(pos)) || s.charAt(pos) == '+' ) { isPositive = true ; pos = s.charAt(pos) == '+' ? pos + 1 : pos; } else if (s.charAt(pos) == '-' ) { isPositive = false ; pos += 1 ; } else { return 0 ; } if (pos == s.length()) return 0 ; while (pos < s.length() && s.charAt(pos) == '0' ) pos += 1 ; if (pos == s.length()) return 0 ; int [] digitRecorder = new int [s.length() - pos]; int digPos = 0 ; while (pos < s.length() && Character.isDigit(s.charAt(pos))) { digitRecorder[digPos++] = s.charAt(pos++) - '0' ; } if (digPos > 11 ) return isPositive ? Integer.MAX_VALUE : Integer.MIN_VALUE; long result = 0 ; long power = 1 ; for (int i = digPos - 1 ; i >= 0 ; i--) { result += digitRecorder[i] * power; if ((isPositive && result > Integer.MAX_VALUE) || (!isPositive && result > Integer.MAX_VALUE + 1L )) { return isPositive ? Integer.MAX_VALUE : Integer.MIN_VALUE; } power *= 10 ; } return isPositive ? (int ) result : -(int ) result; } }
这一版是我写的. 唯一需要注意的是第48行要在1后面加一个L. 因为默认的constant都是int类型. 如果不加L, Integer.MAX_VALUE + 1直接overflow变成Integer.Min_VALUE. 还有就是如果一个数字很长, 但开头不是0, 中间一堆0, 这就会让51行那个power overflow. 这也需要注意. 也就是leading 0要被去掉.
我还发现47 , 48可以改为result > Integer.MAX_VALUE因为如果大于的话, 不管是正是负一律返回最大或最小值. 即使现在刚好等于最小值, 那直接返回也没毛病, 不需要等到超最小值的绝对值的是否再返回.
真就是LC edge lord.
时间复杂度: O(n) 空间复杂度: O(n)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Solution { public int myAtoi (String s) { if (s == null ) return 0 ; boolean isPositive = true ; long result = 0 ; int position = 0 ; StringBuilder semiResult = new StringBuilder (); while (position < s.length() && s.charAt(position) == ' ' ) { position += 1 ; } if (position == s.length()) { return 0 ; } if (s.charAt(position) == '-' || s.charAt(position) == '+' ) { isPositive = s.charAt(position) == '-' ? false : true ; position += 1 ; } while (position < s.length() && Character.isDigit(s.charAt(position))) { if (semiResult.length() == 0 && s.charAt(position) == '0' ) { position += 1 ; continue ; } semiResult.append(s.charAt(position)); position += 1 ; } String sResult = semiResult.toString(); if (sResult.length() == 0 ) return 0 ; if (sResult.length() > 10 ) { return isPositive == true ? Integer.MAX_VALUE : Integer.MIN_VALUE; } result = Long.parseLong(sResult); if (!isPositive) { result *= -1 ; result = result < Integer.MIN_VALUE ? Integer.MIN_VALUE : result; } else if (result > Integer.MAX_VALUE) { result = Integer.MAX_VALUE; } return (int ) result; } }
这个是我之前提交的一次的写法. 这里我是用一个string来存遇到的数字然后用Long.parseLong来转化为数字. 还有就是判断正负号的时候, 我只是判断是否是‘-’或‘+’, 没有判断数字, 因为默认isPositive就是true.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class Solution { public int myAtoi (String input) { int sign = 1 ; int result = 0 ; int index = 0 ; int n = input.length(); while (index < n && input.charAt(index) == ' ' ) { index++; } if (index < n && input.charAt(index) == '+' ) { sign = 1 ; index++; } else if (index < n && input.charAt(index) == '-' ) { sign = -1 ; index++; } while (index < n && Character.isDigit(input.charAt(index))) { int digit = input.charAt(index) - '0' ; if ((result > Integer.MAX_VALUE / 10 ) || (result == Integer.MAX_VALUE / 10 && digit > Integer.MAX_VALUE % 10 )) { return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; } result = 10 * result + digit; index++; } return sign * result; } }
这个是官方给的答案. 比较有趣的是如何从高位开始来算一个数字. 我们第一种方法是把所有的数字从高位到低位依次得到. 然后再从低位加上去. 这个方法则是直接从高位开始. 关键点在于第31, 32行. 这个做法真是天才.
判断overflow的方法也值得我们借鉴. 这个算是一个模板我感觉, 可以记下来.
最后就是这里没有频繁的判断是否index超过了string的长度. 而是在每个if或者循环条件上都加上index < n. 这样保证如何在其中任何一环出现超出长度的情况, 它之下的东西都不会被执行, 一直到达return. 比如第9行出现了超出string范围了, 那么17, 20, 27都不会被执行. 一直跳到44. 这也是值得借鉴的.
时间复杂度: O(n) 空间复杂度: O(1)