Kotlin实现LeetCode算法题之String to Integer (atoi)

题目String to Integer (atoi)(难度Medium)

大意是找出给定字串开头部分的整型数值,忽略开头的空格,注意符号,对超出Integer的数做取边界值处理。

方案1

 1 class Solution {
 2     fun myAtoi(str: String): Int {
 3         val maxInt = "2147483647"
 4         val maxIntS = "+2147483647"
 5         val minIntS = "-2147483648"
 6         val lengthMI = maxInt.length
 7         val lengthMIS = maxIntS.length
 8         var result = ""
 9         var strR = str.trim()
10
11         //strR为空
12         if (strR.isEmpty()) {
13             return 0
14         }
15
16         //strR不为空,且不以+/-开头
17         if (‘+‘ != strR[0] && ‘-‘ != strR[0]) {
18             //不以数字开头
19             if (!strR[0].isDigit()) {
20                 return 0
21             }
22
23             //以数字开头
24             for (c in strR) {
25                 if (c.isDigit()) {
26                     result += c
27                 } else {
28                     break
29                 }
30             }
31             if (result.length > lengthMI ||
32                     (result.length == lengthMI && result > maxInt)) {
33                 result = maxInt
34             }
35             return result.toInt()
36         }
37
38         //strR以+/-开头
39         //后不是跟数字
40         if (strR.length == 1 || (strR.length > 1 && !strR[1].isDigit())) {
41             return 0
42         }
43
44         //后跟数字
45         result += strR[0]
46         for (c in strR.subSequence(1, strR.length)) {
47             if (c.isDigit()) {
48                 result += c
49             } else {
50                 break
51             }
52         }
53         if (result[0] == ‘+‘ && (result.length > lengthMIS ||
54                 (result.length == lengthMIS && result > maxIntS))) {
55             result = maxIntS
56         } else if (result[0] == ‘-‘ && (result.length > lengthMIS ||
57                 (result.length == lengthMIS && result > minIntS))) {
58             result = minIntS
59         }
60         return result.toInt()
61     }
62 }

将数字及其长度这种常量抽象出来,不至于代码中充斥着一丢重复的数字和长度计算,争取在平时的编码过程中养成好习惯。

说到习惯,代码中还有一点提一下,在对字串进行符号存在性、符号后字符等多种情况的判断时并没有使用一长串的if..else..,而是每个小分支直接用return终止。这样的好处是代码可读性与可维护性强,编码过程中不会因分支过多而可能搞混或出现漏处理的情况。

代码先用trim()将字串开头的空字符去除(如果存在的话),然后对有/无符号、是否紧跟数字等多种情况做了清晰的判断和相应的处理。

LeetCode提交详情

从上图看,总共测试了1047个数据,耗时582ms。

测试代码:

1 fun main(args: Array<String>) {
2     val start = System.currentTimeMillis()
3     println(Solution().myAtoi("-0000000000000000006666666bb6aa"))
4     val end = System.currentTimeMillis()
5     println(end - start)
6 }

测试数据

这篇文章先不看算法的耗时,重点关注用于测试的数据。

根据题目的描述,给定字串中应该是可以包含任意字符的,需要我们用代码进行处理,输出要求的结果。

那么,来看几组测试字串及其输出结果:

"   +0aa",0,返回正确的数值0

"   +066bb6aa",66

"   -06 6bb6aa",-6

"   -06666666666666666666bb6aa",-2147483648,数值向下越界

"06666666666666666666bb6aa",2147483647,数值向上越界

"0000000000000000006666666bb6aa",2147483647,???错误的结果,应该是6666666

"a0000000066bb6aa",0,不以符号或数字开头,直接返回0

"- 0000000066bb6aa",0,符号后跟的不是数字,直接返回0

结果分析

可以看到,除了打问号的那一组测试案例,其他均得到了符号要求的结果。即对于不满足要求的字串直接返回0,字串开头的空字符不应影响结果,获取数据过程中遇到非数字立马终止等。

由于题目的描述中并没有具体指明测试字串会是什么样,也没有针对开头很多0的情况进行说明,虽然提交后是accepted状态,但为了算法的严谨性,还是需要对上面出错的情况做进一步的处理。

方案2

 1 class Solution {
 2     fun myAtoi(str: String): Int {
 3         val maxInt = "2147483647"
 4         val maxIntS = "+2147483647"
 5         val minIntS = "-2147483648"
 6         val lengthMI = maxInt.length
 7         val lengthMIS = maxIntS.length
 8         var result = ""
 9         var strR = str.trim()
10
11         //strR为空
12         if (strR.isEmpty()) {
13             return 0
14         }
15
16         //strR不为空,且不以+/-开头
17         if (‘+‘ != strR[0] && ‘-‘ != strR[0]) {
18             //不以数字开头
19             if (!strR[0].isDigit()) {
20                 return 0
21             }
22
23             //以数字开头
24             for (c in strR) {
25                 if (c.isDigit()) {
26                     result += c
27                 } else {
28                     break
29                 }
30             }
31             while (result.length > 1 && result[0] == ‘0‘) {
32                 result = result.removeRange(0, 1)
33             }
34             if (result.length > lengthMI ||
35                     (result.length == lengthMI && result > maxInt)) {
36                 result = maxInt
37             }
38             return result.toInt()
39         }
40
41         //strR以+/-开头
42         //后不是跟数字
43         if (strR.length == 1 || (strR.length > 1 && !strR[1].isDigit())) {
44             return 0
45         }
46
47         //后跟数字
48         result += strR[0]
49         for (c in strR.subSequence(1, strR.length)) {
50             if (c.isDigit()) {
51                 result += c
52             } else {
53                 break
54             }
55         }
56         while (result.length > 2 && result[1] == ‘0‘) {
57             result = result.removeRange(1, 2)
58         }
59         if (result[0] == ‘+‘ && (result.length > lengthMIS ||
60                 (result.length == lengthMIS && result > maxIntS))) {
61             result = maxIntS
62         } else if (result[0] == ‘-‘ && (result.length > lengthMIS ||
63                 (result.length == lengthMIS && result > minIntS))) {
64             result = minIntS
65         }
66         return result.toInt()
67     }
68 }

代码第31-33及56-58行,其实就是针对数据开头的0进行了移除(当然数据只有一个数字且为0是要保留的),因为开头0的存在不会影响数据的大小,反而会干扰字串的长度计算。测试结果:

"-0000000000000000006666666bb6aa",-6666666

时间: 2024-12-15 19:08:11

Kotlin实现LeetCode算法题之String to Integer (atoi)的相关文章

每日算法之八:String to Integer (atoi) 及溢出分析

Implement atoi to convert a string to an integer.  Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.Notes: It is intended for this problem to be spe

LeetCode算法题-Repeated String Match(Java实现)

这是悦乐书的第289次更新,第307篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第156题(顺位题号是686).给定两个字符串A和B,找到A必须重复的最小次数,使得B是它的子字符串. 如果没有这样的解决方案,返回-1.例如: 输入:A ="abcd",B ="cdabcdab". 输出:3 说明:因为重复A三次("abcdabcdabcd"),B是它的子串; 和B不是A重复两次的子串("abcdabcd&

LeetCode算法题-Rotate String(Java实现)

这是悦乐书的第317次更新,第338篇原创 在开始今天的算法题前,说几句,今天是世界读书日,推荐两本书给大家,<终身成长>和<禅与摩托车维修艺术>,值得好好阅读和反复阅读. 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第186题(顺位题号是796).给定两个字符串A和B,在A上进行移位操作,规则是将A最左边的字符移动到最右边去.例如,如果A ='abcde',那么在A上移位一次后,它将是'bcdea'.当且仅当A在A上移位一定次数后可以变为B时返回True.

LeetCode【8】. String to Integer (atoi) --java实现

String to Integer (atoi) Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. Notes: It is intended f

LeetCode【8】string to integer(atoi)

Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. Notes: It is intended for this problem to be spe

LeetCode(8)String to Integer (atoi)

题目: Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. Notes: It is intended for this problem to be

LeetCode算法题-Find All Anagrams in a String(Java实现)

这是悦乐书的第228次更新,第240篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第95题(顺位题号是438).给定一个字符串s和一个非空字符串p,找到s中p的字谜的所有起始索引.字符串仅由小写英文字母组成,字符串s和p的长度不会大于20,100.输出顺序无关紧要.例如: 输入:s:"cbaebabacd" p:"abc" 输出:[0,6] 说明: 起始索引等于0的子字符串是"cba",它是"abc&quo

LeetCode算法题-Number of Lines To Write String(Java实现)

这是悦乐书的第319次更新,第340篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第188题(顺位题号是806).我们要将给定字符串S的字母从左到右写成行.每行最大宽度为100个单位,如果写一个字母会导致该行的宽度超过100个单位,则会写入下一行.给出一个数组宽度,一个数组,其中widths[0]是'a'的宽度,widths[1]是'b'的宽度,widths[25]是'z'的宽度. 现在回答两个问题:S中至少有一个字符有多少行,最后一行使用的宽度是多少?将答案作为长

Leetcode 算法题--ReverseWordsInString

翻转字符串,想到什么写什么...我的做法是先trim掉空格,然后从字符串尾部开始扫描,遇到空格则认为一个单词结束,然后copy这个单词.需要注意的地方在于当扫描到最后一个单词的第一个字母时(譬如the sky is blue的t字母),注意单词长度的自增逻辑. 网上还有人的做法是反转整个字符串,然后逐个翻转单词. 1 package edu.hust.sse.Problems; 2 3 //Given s = "the sky is blue", 4 //return "bl