传送门
D题又被一个奇怪的bug卡了,烦。。
A 上升下降字符串
题目大意
按照题目描述模拟题能有什么大意
解题思路
按照题目描述模拟题能有什么解题思路
代码
class Solution {
public:
bool flag[505];
string sortString(string s) {
int n=s.length();
string ans="";
memset(flag,0,sizeof(flag));
int cnt=0;
while (cnt<n)
{
int last=0;
while (cnt<n)
{
int Min='z'+1;
int loc=-1;
for (int i=0;i<n;++i)
if (!flag[i])
{
if (s[i]<Min&&s[i]>last)
{
Min=s[i];
loc=i;
}
}
if (loc==-1) break;
flag[loc]=1;
++cnt;
ans+=(char)Min;
last=Min;
}
last='z'+1;
while (cnt<n)
{
int Max='a'-1;
int loc=-1;
for (int i=0;i<n;++i)
if (!flag[i])
{
if (s[i]>Max&&s[i]<last)
{
Max=s[i];
loc=i;
}
}
if (loc==-1) break;
flag[loc]=1;
++cnt;
ans+=(char)Max;
last=Max;
}
}
return ans;
}
};
B 每个元音包含偶数次的最长子字符串
题目大意
给出一个只含小写字母的字符串s,求最长的子串,在此子串中a,e,i,o,u出现的次数均为偶数。
1 <= s.length() <= 5*10^5
解题思路
f(k,a,e,i,o,u)表示 以第k个字符结尾的 a,e,i,o,u出现的次数为奇数/偶数的 最长子字符串。
注意只有f(k-1,?,?,?,?)存在才可以转移到f(k,?,?,?,?),或者直接让第k个是开头的字符。(我是不是说了句废话
奇丑无比的代码
class Solution {
public:
int f[500005][2][2][2][2][2];
int findTheLongestSubstring(string s) {
int n=s.size();
memset(f,0,sizeof(f));
switch(s[0])
{
case 'a':{
f[0][1][0][0][0][0]=1;
break;
}
case 'e':{
f[0][0][1][0][0][0]=1;
break;
}
case 'i':{
f[0][0][0][1][0][0]=1;
break;
}
case 'o':{
f[0][0][0][0][1][0]=1;
break;
}
case 'u':{
f[0][0][0][0][0][1]=1;
break;
}
default:{
f[0][0][0][0][0][0]=1;
break;
}
}
for (int i=1;i<n;++i)
{
switch(s[i])
{
case 'a':{
f[i][1][0][0][0][0]=1;
break;
}
case 'e':{
f[i][0][1][0][0][0]=1;
break;
}
case 'i':{
f[i][0][0][1][0][0]=1;
break;
}
case 'o':{
f[i][0][0][0][1][0]=1;
break;
}
case 'u':{
f[i][0][0][0][0][1]=1;
break;
}
default:{
f[i][0][0][0][0][0]=1;
break;
}
}
for (int a=0;a<=1;++a)
for (int b=0;b<=1;++b)
for (int c=0;c<=1;++c)
for (int d=0;d<=1;++d)
for (int e=0;e<=1;++e)
{
if (f[i-1][a][b][c][d][e])
{
switch(s[i])
{
case 'a':{
f[i][a^1][b][c][d][e]=max(f[i][a^1][b][c][d][e],f[i-1][a][b][c][d][e]+1);
break;
}
case 'e':{
f[i][a][b^1][c][d][e]=max(f[i][a][b^1][c][d][e],f[i-1][a][b][c][d][e]+1);
break;
}
case 'i':{
f[i][a][b][c^1][d][e]=max(f[i][a][b][c^1][d][e],f[i-1][a][b][c][d][e]+1);
break;
}
case 'o':{
f[i][a][b][c][d^1][e]=max(f[i][a][b][c][d^1][e],f[i-1][a][b][c][d][e]+1);
break;
}
case 'u':{
f[i][a][b][c][d][e^1]=max(f[i][a][b][c][d][e^1],f[i-1][a][b][c][d][e]+1);
break;
}
default:{
f[i][a][b][c][d][e]=max(f[i][a][b][c][d][e],f[i-1][a][b][c][d][e]+1);
}
}
}
}
}
int ans=0;
for (int i=0;i<n;++i)
ans=max(ans,f[i][0][0][0][0][0]);
return ans;
}
};
C 二叉树中的最长交错路径
题目大意
给出一棵二叉树,求从某个结点出发按照左-右-左或右-左-右往下走到不能走的最长路径。
解题思路
f(i,j)表示从第i个结点 第一步向左/右走的最长路径。
直接dfs转移啊。。。(这算是个树形dp吗
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int f[50005];
int ans=0;
vector<int> get_ans(TreeNode* p)
{
vector<int> pl,pr;
vector<int> re;
int l,r;
if (p->left!=NULL)
{
pl=get_ans(p->left);
l=pl[1]+1;
}
else
l=0;
if (p->right!=NULL)
{
pr=get_ans(p->right);
r=pr[0]+1;
}
else
r=0;
re.push_back(l);
re.push_back(r);
ans=max(ans,l);
ans=max(ans,r);
return re;
}
int longestZigZag(TreeNode* root) {
memset(f,0,sizeof(f));
vector<int> temp=get_ans(root);
return ans;
}
};
D 二叉树搜索子树的最大键值和
题目大意
给出一棵二叉树,求键值和最大的二叉搜索子树。
解题思路
判断一棵树是不是二叉搜索树会么?不会也没关系题面都告诉你怎么判了。
维护Min, Max, Sum, Flag 再dfs就可以了
这题返回用vector爆栈了不知道力扣咋搞的,当时对着stack_overflow看了半天真没想到改成结构体就过了
而且听说这题数据有bug哈哈哈哈哈哈哈哈哈哈但是我的代码你是×不掉的(认真脸
所以这一堆bug加起来你欠我300金币你知道么@力扣(狗头保命
超级优美的代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int MIN=-40001,MAX=40001;
int ans=0;
struct data
{
int Min,Max,Sum,Flag;
};
data get_ans(TreeNode *p)
{
data pl,pr;
data re;
int lmin,lmax,rmin,rmax,lsum,rsum,lflag,rflag;
int Min,Max,Sum,Flag;
if (p->left!=NULL)
{
pl=get_ans(p->left);
lmin=pl.Min;
lmax=pl.Max;
lsum=pl.Sum;
lflag=pl.Flag;
}
else
{
lmin=MAX;
lmax=MIN;
lsum=0;
lflag=1;
}
if (p->right!=NULL)
{
pr=get_ans(p->right);
rmin=pr.Min;
rmax=pr.Max;
rsum=pr.Sum;
rflag=pr.Flag;
}
else
{
rmin=MAX;
rmax=MIN;
rsum=0;
rflag=1;
}
Flag=lflag&&rflag;
if (!(lmax<p->val&&rmin>p->val))
Flag=0;
Sum=lsum+rsum+p->val;
Min=min(lmin,rmin);
Min=min(Min,p->val);
Max=max(lmax,rmax);
Max=max(Max,p->val);
if (Flag)
ans=max(ans,Sum);
re.Min=Min;
re.Max=Max;
re.Sum=Sum;
re.Flag=Flag;
return re;
}
int maxSumBST(TreeNode* root) {
data temp=get_ans(root);
return ans;
}
};