早上起来满脑子都是那个自动机怎么写
剑指 Offer 20. 表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
若干空格
一个 小数 或者 整数
(可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个 整数
若干空格
小数(按顺序)可以分成以下几个部分:
(可选)一个符号字符(‘+’ 或 ‘-’)
下述格式之一:
至少一位数字,后面跟着一个点 ‘.’
至少一位数字,后面跟着一个点 ‘.’ ,后面再跟着至少一位数字
一个点 ‘.’ ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:
(可选)一个符号字符(‘+’ 或 ‘-’)
至少一位数字
部分数值列举如下:
[“+100”, “5e2”, “-123”, “3.1416”, “-1E-16”, “0123”]
部分非数值列举如下:
[“12e”, “1a3.14”, “1.2.3”, “±5”, “12e+5.4”]
过了
自动机
其实就是判断状态的不断转移
就像是每个状态下if-else
这题好妙
我用了数组来表述所以可读性不高,或许像题解一样写会好些
大头在小数点表示部分,我用了四个状态T~T,题解用了三个
class Solution {
public:
bool isNumber(string s) {
int a[15][10]={0},zt;//每行代表一个状态,数值是0代表无法转移状态
//列代表条件 1空格 2符号 3. 4数字 5e/E
a[1][1]=1;a[1][2]=2;a[1][3]=5;a[1][4]=3;
a[2][3]=5;a[2][4]=3;
a[3][3]=4;a[3][4]=3;a[3][5]=7;a[3][1]=10;
a[4][4]=6;a[4][5]=7;a[4][1]=10;
a[5][4]=6;
a[6][1]=10;a[6][4]=6;a[6][5]=7;
a[7][2]=8;a[7][4]=9;
a[8][4]=9;
a[9][4]=9;a[9][1]=10;
a[10][1]=10;
zt=1;//状态从1开始
for(char i:s)
{
//cout<<zt<<endl;
int t;
if(i==' ') t=1;
else if(i=='+'||i=='-') t=2;
else if(i=='.') t=3;
else if(i>='0'&&i<='9') t=4;
else if(i=='e'||i=='E') t=5;
else
return false;
zt=a[zt][t];
//cout<<t<<"---"<<zt<<endl;
if(!zt)
return false;
}
return zt==3||zt==4||zt==6||zt==9||zt==10;
}
};
1819. 序列中不同最大公约数的数目
给你一个由正整数组成的数组 nums 。
数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数。
例如,序列 [4,6,16] 的最大公约数是 2 。
数组的一个 子序列 本质是一个序列,可以通过删除数组中的某些元素(或者不删除)得到。
例如,[2,5,10] 是 [1,2,1,2,4,1,5,10] 的一个子序列。
计算并返回 nums 的所有 非空 子序列中 不同 最大公约数的 数目 。
看了题解
改了好久才过T~T那个动态数组不能用map替代
可能是vector是直接读取内存的原因吧
class Solution {
public:
int countDifferentSubsequenceGCDs(vector<int>& nums) {
int mx=*max_element(nums.begin(),nums.end());
vector<bool> mp(mx+5, false);
for(int i:nums)
mp[i]=true;
int ans=0;
for(int i=1;i<=mx;i++)
{
int t=0;
for(int j=i;j<=mx;j+=i)//关键点
{
if(mp[j])//关键点
{
if(t==0)
t=j;
else
t=__gcd(t,j);
if(t==i)
{
ans++;
break;
}
}
}
}
return ans;
}
};
剑指 Offer 27. 二叉树的镜像
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
想到了之前做的树的题目
用递归真的是神
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
if(root==NULL)
return NULL;
else
{
TreeNode *t=root->left;
root->left=mirrorTree(root->right);
root->right=mirrorTree(t);
return root;
}
}
};
剑指 Offer 28. 对称的二叉树
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
爱上递归,用上递归
其实这些都是那个判断子结构类似的
class Solution {
public:
bool issame(TreeNode *a,TreeNode *b)
{
if(!a&&!b)
return true;
else if(!a||!b)
return false;
else
{
if(a->val==b->val)
return issame(a->left,b->right)&&issame(a->right,b->left);
else
return false;
}
}
bool isSymmetric(TreeNode* root) {
if(!root)
return true;
return issame(root->left,root->right);
}
};
剑指 Offer 29. 顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
纯模拟。。。
看了一下题解以为有简单方法。。没有==那只能老老实实敲代码了
顺时针
也就是走法是固定的
也就是
向右
向下
向左
向上
向右…四个方向不断循环
向右即打印现在下表到右
过了
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int>res;
int y=0,x=0,f=0;//f代表方向
//0向右 1向下 2向左 3向上
int n=matrix.size();
if(n==0)
return res;
int m=matrix[0].size();
int left=-1,right=m,up=-1,down=n;
while(left+1<right&&up+1<down)
{
if(f==0)//向右,当前下一直输出到右边界y不变
{
while(x<right)
{
res.push_back(matrix[y][x]);
x++;
}
f=1;//接下来向下
x--;y++;
up++;//上边界减小
}
else if(f==1)//其他同理
{
while(y<down)
{
res.push_back(matrix[y][x]);
y++;
}
f=2;//接下来向左
y--;x--;
right--;//右边界减小
}
else if(f==2)//其他同理
{
while(x>left)
{
res.push_back(matrix[y][x]);
x--;
}
f=3;//接下来向上
x++;y--;
down--;//下边界减小
}
else
{
while(y>up)
{
res.push_back(matrix[y][x]);
y--;
}
f=0;//接下来向右
y++;x++;
left++;//左边界减小
}
}
return res;
}
};
剑指 Offer 31. 栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。
好眼熟啊==好像很多年前做过
emm中等题?过了欸
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
int i=0,j=0;
int n=pushed.size(),m=popped.size();
if(!n&&!m)
return true;
if(!n||!m)
return false;
stack<int>st;
while(i<n&&j<m)
{
if(st.empty()||st.top()!=popped[j])
{
st.push(pushed[i++]);
}
while(j<m&&!st.empty()&&st.top()==popped[j])
{
st.pop();
j++;
}
}
return i==n&&j==m;
}
};
思路差不多,如果想要简写那就是像题解一样
剑指 Offer 32 - I. 从上到下打印二叉树
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
层次遍历欸
额啊哦好像忘了
啊不对好像用队列就ok
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
queue<TreeNode*>que;
vector<int>v;
if(root==NULL)
return v;
que.push(root);
while(!que.empty())
{
TreeNode *t=que.front();
que.pop();
if(t!=nullptr)
{
v.push_back(t->val);
que.push(t->left);
que.push(t->right);
}
}
return v;
}
};
过了>_<?中等题么
剑指 Offer 32 - II. 从上到下打印二叉树 II
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
太奇怪了
可能是分类错了==一是中等题,二居然是简单题
这个计算层数emmm我记得当初数据结构上机考试我想到一个方法来着的
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>>v;
queue<TreeNode*>que;
int index=0,num=1,nxt=0;//num当前层数剩余个数,nxt下一层数计数
if(!root)
return v;
que.push(root);
v.push_back(vector<int>());
while(!que.empty())
{
TreeNode *t=que.front();
que.pop();
v[index].push_back(t->val);
if(t->left!=NULL)
{
que.push(t->left);
nxt++;
}
if(t->right!=NULL)
{
que.push(t->right);
nxt++;
}
if(--num==0)//当前一层空了
{
num=nxt;
index++;
nxt=0;
if(!que.empty())
v.push_back(vector<int>());
}
}
return v;
}
};
对哦其实不需要计数
就是每次打印完这层
当前队列的个数就是等于这一层的层数
好妙
剑指 Offer 53 - I. 在排序数组中查找数字 I
统计一个数字在排序数组中出现的次数。
class Solution {
public:
int search(vector<int>& nums, int target) {
int res=0;
for(int i:nums)
if(i==target)
res++;
return res;
}
};
这也可以2分emmm
剑指 Offer 53 - II. 0~n-1中缺失的数字
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
害这里用二分吧
二分的边界好难调
调了十几分钟ok了
class Solution {
public:
int missingNumber(vector<int>& nums) {
int l=0,r=nums.size()-1;
if(nums[0]==1)
return 0;
if(nums[r]==r)
return r+1;
while(l<r)
{
int mid=(l+r)/2;
if(nums[mid]!=mid)
r=mid;
else
{
l=mid+1;
}
}
return l;
}
};
剑指 Offer 32 - III. 从上到下打印二叉树 III
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
用双向队列就ok
从左到右取
从右到左取
不同取法的时候放法也不同
yeah~>_<打败百分之百的时间
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
int index=0,f=0;//f=0从左到右,f=1从右到左
vector<vector<int>>v;
if(root==NULL)
return v;
deque<TreeNode*>que;
que.push_back(root);
v.push_back(vector<int>());
while(!que.empty())
{
deque<TreeNode*>que2;
int len=que.size();
for(int i=0;i<len;i++)
{
TreeNode *t;
if(!f)
{
t=que.front();
que.pop_front();
v[index].push_back(t->val);
if(t->left!=NULL)
que2.push_back(t->left);
if(t->right!=NULL)
que2.push_back(t->right);
}
else
{
t=que.back();
que.pop_back();
v[index].push_back(t->val);
if(t->right!=NULL)
que2.push_front(t->right);
if(t->left!=NULL)
que2.push_front(t->left);
}
}
f=~f;
if(!que2.empty())
v.push_back(vector<int>());
que=que2;
index++;
}
return v;
}
};
剑指 Offer 33. 二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
这题应该跟树没啥关系吧?
找出对应的规则判断?
噢噢二叉搜索树
也就是左边的值要小于节点值,右边的值也需要小于节点值
一个猜想,从头开始遍历,当前节点的值至少小于
emm写一下其他东西打游戏把这题放明天今天先到这里吧