LeetCode 第21场双周赛 题解

传送门
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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值