算法入门 04模拟(中等 - 第一题)LeetCode 8
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法入门 04模拟(中等 - 第一题)LeetCode 8相关的知识,希望对你有一定的参考价值。
🙉饭不食,水不饮,题必须刷🙉
还不会C语言,和我一起打卡! 🌞《光天化日学C语言》🌞
LeetCode 太难?上简单题! 🧡《C语言入门100例》🧡
LeetCode 太简单?大神盘他! 🌌《夜深人静写算法》🌌
一、题目
1、题目描述
实现一个
myAtoi(string s)
函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。函数 myAtoi(string s) 的算法如下:
1)读入字符串并丢弃无用的前导空格;
2)检查下一个字符为正还是负号,读取该字符。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
3)读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。将前面步骤读入的这些数字转换为整数。如果没有读入数字,则整数为 0 。
4)如果整数超过 32 位有符号整数范围 [ − 2 31 , 2 31 − 1 ] [−2^{31}, 2^{31} − 1] [−231,231−1],需要截断这个整数,使其保持在这个范围内。具体来说,小于 − 2 31 −2^{31} −231 的整数应该被固定为 − 2 31 −2^{31} −231 ,大于 2 31 − 1 2^{31} − 1 231−1 的整数应该被固定为 2 31 − 1 2^{31} − 1 231−1。
返回整数作为最终结果。
样例1:"+123",输出:123
样例2:" -123",输出 − 123 -123 −123
样例3:“hahaha 996”,输出 0
样例4:"-9231243283324473242332",输出 -2147483648
样例5:"-+1",输出 0
2、基础框架
- c++ 版本给出的基础框架代码如下,给定一个字符串,返回一个整数。
class Solution {
public:
int myAtoi(string s) {
}
};
3、原题链接
二、解题报告
1、思路分析
这个就是一个典型的模拟题,题目很简单,就是给定一个字符串,我们需要将它转换成整型返回。然而要考虑很多的点,接下来我们一一分析:
1)需要去除前导空格;
2)判断第一个字符:
2.a)如果第 1 个符号是'+'
,则取从第 2 个符号开始的子串;
2.b)如果第 1 个符号是'-'
,则取从第 2 个符号开始的子串,并且记录符号位;
2.c)否则,什么都不做;
3)遍历得到的字符串,不断计算累加和,如果等到的数超出int
范围,按照最大值还是最小值分情况返回,或者遇到不是数字的字符,就跳出循环;
4)返回当前的累加和 乘上 符号位 的结果。
2、时间复杂度
- 基本所有的操作都是一层
for
循环枚举,所以时间复杂度为 O ( n ) O(n) O(n)。
3、代码详解
class Solution {
public:
string trim(string s) { // (1)
string ret;
int notEmptyIdx = s.size();
for(int i = 0; i < s.size(); ++i) {
if( s[i] == ' ' ) {
continue;
}else {
notEmptyIdx = i;
break;
}
}
for(int i = notEmptyIdx; i < s.size(); ++i) {
ret.push_back( s[i] );
}
return ret;
}
string positiveCheck(string s) { // (2)
string ret;
for(int i = 1; i < s.size(); ++i) {
ret.push_back(s[i]);
}
return ret;
}
string negtaiveSplit(string s, int &flag) { // (3)
if(s.size() == 0) {
flag = 1;
return s;
}
if(s[0] == '-') {
flag = -1;
string ret;
for(int i = 1; i < s.size(); ++i) {
ret.push_back(s[i]);
}
return ret;
}
flag = 1;
return s;
}
int myAtoi(string s) {
int flag = 1;
long long sum = 0; // (4)
s = trim(s);
if(s.size() == 0) {
return 0;
}
if(s[0] == '+')
s = positiveCheck(s);
else if(s[0] == '-')
s = negtaiveSplit(s, flag);
long long minv = INT_MIN;
long long maxv = INT_MAX;
for(int i = 0; i < s.size(); ++i) {
if(s[i] >= '0' && s[i] <= '9') {
sum = sum * 10 + s[i] - '0';
if(sum * flag < minv) {
return minv; // (5)
}
if(sum * flag > maxv) {
return maxv; // (6)
}
}else {
break; // (7)
}
}
return sum * flag; // (8)
}
};
-
(
1
)
(1)
(1)
string trim(string s)
这个函数就是传入字符串s
,返回一个去掉前导空格的字符串,这一步的时间复杂度为 O ( n ) O(n) O(n)。 -
(
2
)
(2)
(2)
string positiveCheck(string s)
函数的作用,是去掉第一个字符为'+'
的情况,并且返回字符串,这一步的时间复杂度也为 O ( n ) O(n) O(n)。 -
(
3
)
(3)
(3)
string negtaiveSplit(string s, int &flag)
函数的作用,是对于负数的处理,将符号存储到flag
变量中,并且通过引用返回。 -
(
4
)
(4)
(4) 用
long long
是因为需要考虑int
越界的情况; -
(
5
)
(5)
(5) 超过
int
最小值; -
(
6
)
(6)
(6) 超过
int
最大值; - ( 7 ) (7) (7) 出现非法符号;
-
(
8
)
(8)
(8) 考虑负数的存在,所以需要乘上
flag
。
三、本题小知识
int
越界的情况,可以使用long long
来化解。
以上是关于算法入门 04模拟(中等 - 第一题)LeetCode 8的主要内容,如果未能解决你的问题,请参考以下文章
算法入门广度优先搜索(中等 - 第一题)LeetCode 994
算法入门 05深度优先搜索(中等 - 第一题)LeetCode 695