找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
class Solution {
public:
int findRepeatNumber(vector& nums) {
unordered_map mp;
for(auto& num:nums)
{
mp[num]++;
if(mp[num]>1) return num;
}
return 0;
}
};
https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/mian-shi-ti-03-shu-zu-zhong-zhong-fu-de-shu-zi-yua/
class Solution {
public:
int findRepeatNumber(vector& nums) {
int i = 0;//初始序号
while(i < nums.size()) {//在范围内就不断循环
if(nums[i] == i) {//加一个判断,当索引等于对应值,索引值自加才会触发
i++;
continue;
}
if(nums[nums[i]] == nums[i])//根据索引值来找值,发生重复
return nums[i];
swap(nums[i],nums[nums[i]]);
}
return -1;
}
};
// 作者:jyd
// 链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/mian-shi-ti-03-shu-zu-zhong-zhong-fu-de-shu-zi-yua/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5
,返回 true
。
给定 target = 20
,返回 false
。
限制:
0 <= n <= 1000
0 <= m <= 1000
class Solution {
public:
bool findNumberIn2DArray(vector>& matrix, int target) {
int row = matrix.size();
if(row==0) return false;
int col = matrix[0].size();
for(int i=row-1,j=0;i>=0&&j target) i--;
else j++;
}
return false;
}
};
难度简单165
请实现一个函数,把字符串 s
中的每个空格替换成"%20"。
示例 1:
输入:s = "We are happy."
输出:"We%20are%20happy."
限制:
0 <= s 的长度 <= 10000
class Solution {
public:
string replaceSpace(string s) {
string res;
for(char& ch:s)
{
if(ch==' ')
{
res+="%20";
}
else
res+=ch;
}
return res;
}
};
class Solution {
public:
string replaceSpace(string s) {
int cnt = 0;
int size = s.size();
//统计空格数量
for(char ch:s)
{
if(ch==' ') cnt++;
}
s.resize(size+cnt*2);
int nsize = s.size();
//更改原字符串
for(int i=size-1,j=nsize-1;i
难度简单195
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
class Solution {
private:
vector vct;//定义向量
void recur(ListNode* head)//递归函数
{
if(head==NULL) return;//边界条件,节点为空
recur(head->next);//递归下一节点
vct.emplace_back(head->val);//往向量中放入对应值
}
public:
vector reversePrint(ListNode* head) {
recur(head);//递归,寻找头节点
return vct;//返回向量
}
};
class Solution {
public:
vector reversePrint(ListNode* head) {
// recur(head);
vector vct;
stack st;
while(head!=NULL)//终止条件
{
st.push(head->val);
head= head->next;//不断枚举
}
while(!st.empty())
{
vct.emplace_back(st.top());//取栈顶元素
st.pop();//弹出栈顶元素
}
return vct;
}
};
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
示例 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
限制:
0 <= 节点个数 <= 5000
class Solution {
public:
TreeNode* buildTree(vector& preorder, vector& inorder) {
this->preorder = preorder;
for(int i = 0; i < inorder.size(); i++)
dic[inorder[i]] = i;
return recur(0, 0, inorder.size() - 1);
}
private:
vector preorder;
unordered_map dic;
TreeNode* recur(int root, int left, int right) {
if(left > right) return nullptr; // 递归终止
TreeNode* node = new TreeNode(preorder[root]); // 建立根节点
int i = dic[preorder[root]]; // 划分根节点、左子树、右子树
node->left = recur(root + 1, left, i - 1); // 开启左子树递归
node->right = recur(root + i - left + 1, i + 1, right); // 开启右子树递归
return node; // 回溯返回根节点
}
};
// 作者:Krahets
// 链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/99ljye/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例 1:
输入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
输出:[null,null,3,-1]
提示:
1 <= values <= 10000
最多会对 appendTail、deleteHead 进行 10000 次调用
栈st1模拟入队列,栈st2模拟出队列,当st2中没有元素的时候,再将st1中的元素装填到st2中,如果在st2中有元素的时候将st1的元素装填到st2中,就会导致st2栈顶的元素不是队首元素。
class CQueue {
private:
stack st1,st2;//入队列,出队列
public:
CQueue() {
}
void appendTail(int value) {
st1.push(value);//入队列
}
int deleteHead() {
if(st2.empty())//模拟出队列为空
{
if(st1.empty()) return -1;//模拟入队列为空
while(!st1.empty())//将st1中的元素装到st2中
{
int cur = st1.top();
st1.pop();
st2.push(cur);
}
}
int cur = st2.top();
st2.pop();
return cur;
}
};
写一个函数,输入 n
,求斐波那契(Fibonacci)数列的第 n
项(即 F(N)
)。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:1
示例 2:
输入:n = 5
输出:5
class Solution {
public:
int fib(int n) {
if(n<2) return n;
const int MOD = 1e9+7;
vector F(3,0);
F[1] = 1;
for(int i=1;i
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:2
示例 2:
输入:n = 7
输出:21
示例 3:
输入:n = 0
输出:1
提示:
0 <= n <= 100
class Solution {
public:
int climbStairs(int n) {
vector F(3,0);//构造初始数组
F[1] = 1;//初始值定义
F[2] = 2;
if(n<3) return F[n];//n如果小于三就返回初始值
for(int i=3;i<=n;i++)//遍历更新,当前阶的跳法等于前一阶和前前阶的和
{
F[0] = F[1];//原先的数组中的值左移,挪出2来存储最近的结果
F[1] = F[2];
F[2] = F[0]+F[1];
}
return F[2];//我们要的结果必然存储在F[2]
}
};
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
示例 1:
输入:[3,4,5,1,2]
输出:1
示例 2:
输入:[2,2,2,0,1]
输出:0
这道题是 寻找旋转排序数组中的最小值 的延伸题目。
允许重复会影响算法的时间复杂度吗?会如何影响,为什么?
答:允许重复会影响时间复杂度,重复的时候,需要遍历比当前序号小1的序号,如果重复元素很多的话,会近似为O(n)算法,因为需要从右到左逐个比较,避免遗漏掉最小值。
class Solution {
public:
int findMin(vector& numbers) {
int size = numbers.size();
int left = 0,right = size-1;
while(leftnumbers[right])
{
left = mid+1;
}
else if(numbers[mid]
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
提示:
1 <= board.length <= 200
1 <= board[i].length <= 200
board
和 word
仅由大小写英文字母组成
class Solution {
private:
vector> isVisited;//标记数组,表示是否访问过
vector> board;
string s;
int size;
int row;
int col;
bool dfs(int i,int j,int index)
{
if(index==size-1)//边界条件
{
return true;
}
if(i-1>=0&&isVisited[i-1][j]==0&&board[i-1][j]==s[index+1])//往上
{
isVisited[i-1][j]=1;
if(dfs(i-1,j,index+1)==true) return true;
isVisited[i-1][j]=0;
}
if(i+1=0&&isVisited[i][j-1]==0&&board[i][j-1]==s[index+1])//往左
{
isVisited[i][j-1]=1;
if(dfs(i,j-1,index+1)==true) return true;
isVisited[i][j-1]=0;
}
if(j+1 >& board, string word) {
row = board.size();
col = board[0].size();
s = word;
size = word.size();
this->board = board;
for(int i=0;i>(row,vector(col,0));
if(word[0]==board[i][j])
{
isVisited[i][j] = 1;
if(dfs(i,j,0)==true)
return true;
isVisited[i][j] = 0;
}
}
}
return false;
}
};
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
示例 1:
输入:m = 2, n = 3, k = 1
输出:3
提示:
1 <= n,m <= 100
0 <= k <= 20
class Solution {
private:
vector> isVisited;//标记访问与否
int k,m,n;
int res = 0;
bool check(int x,int y)
{
int ans = 0;
while(x)
{
ans+=x%10;
x/=10;
}
while(y)
{
ans+=y%10;
y/=10;
}
return ans>k?false:true;
}
void dfs(int x,int y)
{
//深搜的时候需要判断范围,是否访问过,以及是否数位之和小于等于k
if(x+1>(m,vector(n,0));
this->k = k;
this->m = m;
this->n = n;
if(check(0,0))
{
isVisited[0][0] = 1;
dfs(0,0);
res++;
}
return res;
}
};
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
提示:
2 <= n <= 58
动态规划,转移方程:dp[j] = max(dp[j],max((j-i)*i,dp[j-i]*i))
class Solution {
public:
int cuttingRope(int n) {
vector dp(n+1,0);
for(int i=1;i
https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/solution/mian-shi-ti-14-ii-jian-sheng-zi-iitan-xin-er-fen-f/
结论:长度4以下打表,长度如果大于4,就尽量按长度3来切割这样子乘积有最大值
class Solution {
public:
int integerBreak(int n) {
if(n==2) return 1;
else if(n==3) return 2;
else if(n==4) return 4;
// const int MOD = 1e9+7;/
long res = 1;
while(n>4)
{
n-=3;
res=res*3;
}
if(n==2) return (int)(res*2);
else if(n==3) return (int)(res*3);
else if(n==4) return (int)(res*4);
return 0;
}
};
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m - 1] 。请问 k[0]k[1]…*k[m - 1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1
提示:
2 <= n <= 1000
https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/solution/mian-shi-ti-14-ii-jian-sheng-zi-iitan-xin-er-fen-f/
结论:长度4以下打表,长度如果大于4,就尽量按长度3来切割这样子乘积有最大值
class Solution {
public:
int integerBreak(int n) {
if(n==2) return 1;
else if(n==3) return 2;
else if(n==4) return 4;
// const int MOD = 1e9+7;/
long res = 1;
while(n>4)
{
n-=3;
res=res*3;
}
if(n==2) return (int)(res*2);
else if(n==3) return (int)(res*3);
else if(n==4) return (int)(res*4);
return 0;
}
};
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为 汉明重量).)。
提示:
-3
。示例 3:
输入:n = 4294967293 (控制台输入 11111111111111111111111111111101,部分语言中 n = -3)
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。
数1的个数
class Solution {
public:
int hammingWeight(uint32_t n) {
int res = 0;
while(n!=0)
{
if((n&1)==1) res++;
n>>=1;
}
return res;
}
};
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。
示例 1:
输入:x = 2.00000, n = 10
输出:1024.00000
示例 2:
输入:x = 2.10000, n = 3
输出:9.26100
class Solution {
public double myPow(double x, int n) {
if(n==0) return 1;//任何数的0次方都是0
long b = n;//因为取绝对值可能会越界
if(b<0)//幂为负,先取倒数
{
x = 1/x;
b = -b;
}
double res = 1;//结果
while(b>0)//直到把幂次用完
{
if((b&1)==1) res*=x;//当前位还有数,就表示要多乘以一个x
b = (b>>1);//当最低位没了1,右移,将x扩大一倍,加快运算
x*=x;//x扩大一倍
}
return res;
}
}
当n=0,n=1,n=-1的时候判断一下,并且要额外对n取一下余数,避免漏乘
class Solution {
public:
double myPow(double x, int n) {
if(n==0) return 1;
else if(n==1) return x;
else if(n==-1) return 1/x;
double num = myPow(x,n/2);
return num*num*myPow(x,n%2);
}
};
输入数字 n
,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
示例 1:
输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]
深搜每一位数对应的情况
class Solution {
private:
vector res;
void DFS(int n, int count, string record)
{
if (count == n)
{
if (record.front() != '0') res.push_back(record);
return;
}
for (int index = 0; index <= 9; index++)
{
if (record.size() && record.front() == '0')
{
DFS(n, count + 1, to_string(index));
}
else
{
DFS(n, count + 1, record + to_string(index));
}
}
}
public:
vector printNumbers(int n) {
DFS(n, 0, "");
vector intRes;
for (vector::iterator iter = res.begin(); iter != res.end(); iter++)
{
intRes.push_back(stoi(*iter));
}
return intRes;
}
};
// 作者:Coca Cola
// 链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5912jv/?discussion=q7DffZ
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
一轮枚举所有情况
class Solution {
public:
vector printNumbers(int n) {
vector res;
int maxN = 1;
for(int i=0;i
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
**注意:**此题对比原题有改动
示例 1:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
if(head->val==val) return head->next;
ListNode* node = head->next;
ListNode* pre = head;
while(node!=NULL)
{
if(node->val==val)
{
pre->next = node->next;
break;
}
pre = node;
node = node->next;
}
return head;
}
};
请实现一个函数用来匹配包含'. '
和'*'
的正则表达式。模式中的字符'.'
表示任意一个字符,而'*'
表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"
与模式"a.a"
和"ab*ac*a"
匹配,但与"aa.a"
和"ab*a"
均不匹配。
示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
s
可能为空,且只包含从 a-z
的小写字母。
p
可能为空,且只包含从 a-z
的小写字母以及字符 .
和 *
,无连续的 '*'
。
https://leetcode-cn.com/problems/regular-expression-matching/solution/liang-chong-shi-xian-xiang-xi-tu-jie-10-48bgj/
class Solution {
private:
bool match(char a,char b)//匹配字符
{
if(a==b||b=='.') return true;//a==b或者模板串对应的字符是.就说明匹配
else return false;//否则不匹配
}
public:
bool isMatch(string s, string p) {
int sSize = s.size();//字符串s的长度
int pSize = p.size();//字符串p的长度
vector> dp(sSize+1,vector(pSize+1,0));//动态规划向量,初始化为全零向量
dp[0][0] = 1;//匹配空串返回1
for(int i=0;i<=sSize;i++)//枚举s中的每个字符
{
for(int j=1;j<=pSize;j++)//枚举p中的每个字符
{
if(p[j-1]=='*')//假如第j个字符是*号
{
dp[i][j] |= dp[i][j-2];//更新dp状态
if(i>0&&match(s[i-1],p[j-2]))//匹配s的第i个字符和p的第j-1个字符,假如两者一致,就更新dp值
{
dp[i][j] |= dp[i-1][j];
}
}else
{
if(i>0&&match(s[i-1],p[j-1]))
{
dp[i][j] |= dp[i-1][j-1];
}
}
}
}
return dp[sSize][pSize];//返回右下角最后一个状态,就是所要的结果
}
};
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
'e'
或 'E'
,后面跟着一个 整数小数(按顺序)可以分成以下几个部分:
'+'
或 '-'
)'.'
'.'
,后面再跟着至少一位数字'.'
,后面跟着至少一位数字整数(按顺序)可以分成以下几个部分:
'+'
或 '-'
)部分数值列举如下:
["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
部分非数值列举如下:
["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]
示例 1:
输入:s = "0"
输出:true
class Solution {
public:
bool isNumber(string s) {
// 利用状态机
int state = 0;//表示状态,初始状态为0
for(char& ch:s)//枚举每一个字符
{
switch(state){
case 0://初始状态,
if(ch==' ') state = 1;//输入空格前往状态1
else if(ch=='+'||ch=='-') state = 2;//输入正负号前往状态2
else if(ch>='0'&&ch<='9') state = 3;//输入0到9前往状态3
else if(ch=='.') state = 10;//输入小数点,前往状态10
else return false;//出现了其它输入,判错
break;
case 1:
if(ch==' ') state = 1;//输入空格保持原样
else if(ch=='+'||ch=='-') state = 2;//输入正负号前往状态2
else if(ch>='0'&&ch<='9') state = 3;//输入0到9前往状态3
else if(ch=='.') state = 10;//输入小数点,前往状态10
else return false;//出现了其它输入,判错
break;
case 2:
if(ch>='0'&&ch<='9') state = 3;//输入0到9前往状态3
else if(ch=='.') state = 10;//输入小数点,前往状态10
else return false;//出现了其它输入,判错
break;
case 3:
if(ch>='0'&&ch<='9') state = 3;//输入0到9保持原样
else if(ch=='.') state = 4;//输入小数点前往状态4
else if(ch=='e'||ch=='E') state = 6;//输入E,前往状态6
else if(ch==' ') state = 9;//输入空格前往状态9
else return false;//出现了其它输入,判错
break;
case 4:
if(ch>='0'&&ch<='9') state = 5;//输入0到9前往状态5
else if(ch=='e'||ch=='E') state = 6;//输入E,前往状态6
else if(ch==' ') state = 9;//输入空格,前往状态9
else return false;//出现其他输入,判错
break;
case 5:
if(ch>='0'&&ch<='9') state = 5;//输入0到9保持原样
else if(ch=='e'||ch=='E') state = 6;//输入E,前往状态6
else if(ch==' ') state = 9;//输入空格前往状态9
else return false;//出现其他输入,判错
break;
case 6:
if(ch>='0'&&ch<='9') state = 7;//输入0到9前往状态7
else if(ch=='+'||ch=='-') state = 8;//输入正负号前往状态8
else return false;//出现其他输入,判错
break;
case 7:
if(ch>='0'&&ch<='9') state = 7;//输入0到9保持原样
else if(ch==' ') state = 9;//输入空格前往状态9
else return false;//出现其他输入,判错
break;
case 8:
if(ch>='0'&&ch<='9') state = 7;//输入0到9前往状态7
else return false;//出现其他输入,判错
break;
case 9:
if(ch==' ') state = 9;//输入空格保持原样
else return false;//出现其他输入,判错
break;
case 10:
if(ch>='0'&&ch<='9') state = 11;//输入0到9前往状态11
// else if(ch=='e'||ch=='E') state = 15;//输入E,前往状态15
else return false;//出现其他输入,判错
break;
case 11:
if(ch>='0'&&ch<='9') state = 11;//输入0到9保持原样
else if(ch==' ') state = 9;//输入空格前往状态9
else if(ch=='e'||ch=='E') state = 12;//输入E,前往状态12
else return false;//出现其他输入,判错
break;
case 12:
if(ch>='0'&&ch<='9') state = 13;//输入0到9前往状态13
else if(ch=='+'||ch=='-') state = 13;//输入正负号前往状态13
else return false;//出现其他输入,判错
break;
case 13:
if(ch>='0'&&ch<='9') state = 13;//输入0到9保持不变
else if(ch==' ') state = 14;//输入空格前往状态14
else return false;//出现其他输入,判错
break;
case 14:
if(ch==' ') state = 14;//输入空格保持不变
else return false;//出现其他输入,判错
break;
default:
break;
}
}
if(state==3||state==4||state==5||state==7||state==9||state==11||state==13||state==14) return true;//假如最后的状态是3,说明结尾是一个数字,假如最后的状态是4,说明是一个小数点,假如最后的状态是5,说明结尾是个数字,并且是小数,假如最后的状态为7,就说明是E后面跟了整数,假如最后状态为9,就说明结尾是空格,假如最后状态为11说明是“.数字”的格式
return false;//否则说明不是
}
};
class Solution {
public:
int integer(string& s, int n) {
while (s[n] != '\0') {
if (s[n] < '0' || s[n] > '9') break;
n ++;
}
// n指向下一个
return n;
}
int integerAOrDecimal(string& s, int n){
int n_orig1 = n;
n = integer(s, n);
int n_vary1 = n;
// 判断是否是整数
if (s[n] != '.'){
return n_vary1 == n_orig1 ? -1 : n_vary1;
}
// 判断是否是小数
// 跨过小数点
n ++;
int n_orig2 = n;
n = integer(s, n);
int n_vary2 = n;
if (n_orig1 == n_vary1 && n_orig2 == n_vary2) return -1;
return n_vary2;
}
bool isNumber(string s) {
int n = 0;
// 处理前面的若干空格
while (s[n] == ' ') n ++;
// 跨过正负号
if (s[n] == '+' || s[n] == '-') n ++;
// 判断小数或者整数
n = integerAOrDecimal(s, n);
if (n == -1) return false;
// 可选是不是存在e\E
if (s[n] == 'e' || s[n] == 'E') {
n ++;
if (s[n] == '+' || s[n] == '-') n ++;
int n_orig = n;
n = integer(s, n);
if (n_orig == n) return false;
}
// 判断结尾空格
while (s[n] != '\0') {
if (s[n] != ' ') return false;
n ++;
}
return true;
}
};