您的位置:首页 > 编程语言 > Go语言

LeetCode-Algorithms #008 String to Integer(atoi), Database #183 Customers Who Never Order

2018-10-09 16:47 603 查看

 

 LeetCode-Algorithms #008 String to Integer(atoi)

题目这里的atoi是ASCII to Integer的意思, 所以读作a to i可能比较合理.

给定一个字符串, 将其转换成数字, 具体规则比较繁琐, 可以看上面图中的例子.

题目本身是比较简单的, 但是因为陷阱很多, 需要注意的地方也很多, 所以如果想要一次通过就非常困难, 我自己是反复修改了很多次:

1 class Solution {
2     public int myAtoi(String str) {
3         //如果原字符串是null, 就直接返回0
4         if (str == null)
5             return 0;
6         //去掉原串前面的空格
7         //这里直接用trim实际上是比较犯规的,但是有点懒得写了
8         str = str.trim();
9         //去掉空格后如果变成了空串, 就直接返回0
10         if (str.length() == 0)
11             return 0;
12         //创建一个sign表示正负号
13         int sign = 1;
14         //此时如果字符串以-/+开头就记录下符号然后把符号去掉
15         if (str.charAt(0) == '-') {
16             sign = -1;
17             str = str.substring(1);
18             if (str.length() == 0)
19                 return 0;
20         } else if (str.charAt(0) == '+') {
21             sign = 1;
22             str = str.substring(1);
23             if (str.length() == 0)
24                 return 0;
25         }
26         //此时字符串如果以0开头,就把这些0去掉
27         while (str.length() > 0 && str.charAt(0) == '0') {
28             str = str.substring(1);
29         }
30         //此时如果字符串变成了空串,就直接返回0
31         if (str.length() == 0)
32             return 0;
33         //此时如果字符串以数字开头,则继续判断,以其他字符开头就直接返回0
34         if (str.charAt(0) >= '0' && str.charAt(0) <= '9') {
35             //将此时的字符串转换为字符数组
36             char[] arr = str.toCharArray();
37             //建立一个StringBuilder对象存储结果
38             StringBuilder sb = new StringBuilder();
39             //对字符数组进行遍历, 如果遍历到第11位仍是数字, 则必然已经超过32位整数的取值范围,可以停止遍历
40             //这样做的另一个好处是可以避免超过long的取值范围
41             for (int i = 0; i < arr.length && i < 11; i++) {
42                 //如果字符数组相应位置是数字,就添加到结果中
43                 if (arr[i] >= '0' && arr[i] <= '9') {
44                     sb.append(arr[i]);
45                 } else { //如果出现不是数字的字符,就停止遍历
46                     break;
47                 }
48             }
49             //将结果转换成字符串
50             String s = sb.toString();
51             //用一个long值接收字符串转换的结果, 再乘以之前记录下的符号
52             long ans = Long.parseLong(s) * sign;
53             //对结果进行判断, 如果超过int的取值范围, 就直接返回上/下界
54             if (ans > Integer.MAX_VALUE)
55                 return Integer.MAX_VALUE;
56             if (ans < Integer.MIN_VALUE)
57                 return Integer.MIN_VALUE;
58             //否则就强转为int返回结果
59             return (int) ans;
60         } else {
61             //其他非法结果直接返回0
62             return 0;
63         }
64     }
65 }

可以看出, 需要进行判断和注意的地方相当多, 第一次就能够在面对诸如" ", "20000000000000000000000000000000000000", "+1", "000000000000012345678"等等input时都作出正确的判断真是不容易(嗯, 前面这几个坑每一个我都掉进去了😂)

整体看来性能普普通通吧, 但是和第一梯队差距也不太大, 但是确实有不少细节处理上都不够漂亮, 看看别人的答案:

1 class Solution {
2     public int myAtoi(String str) {
3         // 1. whether valid input
4         if (str == null || str.length() == 0) {
5             return 0;
6         }
7         int sign = 1;
8         int result = 0;
9         int start = 0;
10         // 2. trim white space
11         while (start < str.length() && str.charAt(start) == ' ') {
12             start++;
13         }
14         // 3. find sign
15         if (start < str.length() && (str.charAt(start) == '-' || str.charAt(start) == '+')) {
16             sign = str.charAt(start) == '-' ? -1 : 1;
17             start++;
18          }
19         // 4. calculate result
20         // when iterate at Alphabet, break
21         for (int i = start; i < str.length(); i++) {
22             int tmp = str.charAt(i) - '0';
23            if (tmp > 9 || tmp < 0) {
24                 break;
25             } else if (result > Integer.MAX_VALUE / 10 || result == Integer.MAX_VALUE / 10
26                        && Integer.MAX_VALUE % 10 < tmp) {
27                 return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
28             }
29             else {
30                 result = result * 10 + tmp;
31             }
32         }
33         return result * sign;
34     }
35 }
1 class Solution {
2     public int myAtoi(String str) {
3         if (str == null || str.length() == 0) {
4             return 0;
5         }
6
7         int sign = 1;
8         long result = 0;
9
10         for (int i = 0; i < str.length(); i++) {
11             char c = str.charAt(i);
12
13             if (c != ' ') {
14                 int j = i;
15
16                 if (c == '-') {
17                     sign = -1;
18                     j = i + 1;
19                 } else if (c == '+') {
20                     sign = 1;
21                     j = i + 1;
22                 }
23
24                 while (j < str.length() && Character.isDigit(str.charAt(j))) {
25                     long temp = result;
26                     int digit = str.charAt(j) - '0';
27                     result = (result * 10) + (sign * digit);
28
29                     if (result > Integer.MAX_VALUE) {
30                         return Integer.MAX_VALUE;
31                     } else if (result < Integer.MIN_VALUE) {
32                         return Integer.MIN_VALUE;
33                     }
34
35                     j += 1;
36                 }
37
38                 return (int) result;
39             }
40         }
41
42         return 0;
43     }
44 }

这两个答案都各有不少可取之处, 思路其实也很接近, 就不具体介绍了

 

 

 

LeetCode-Database #183 Customers Who Never Order

有两个表Customers和Orders, 找出从来没有下过订单的顾客们的名字

真的没啥好说的:

SELECT Name AS Customers
FROM Customers
WHERE Customers.Id NOT IN
(SELECT CustomerId
FROM Orders
);

不过我竟然没忘了NOT IN这个东西, 还是不错的哈哈.

参考一下别人的答案, 其实还可以用左外联结来写:

SELECT
C.Name AS Customers
FROM
Customers C
LEFT JOIN Orders O
ON C.Id = O.CustomerId
WHERE
O.CustomerId IS NULL;

但是似乎没有第一种快

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: