【leetcode】第 21 场双周赛

230 篇文章 0 订阅
9 篇文章 0 订阅

赛后总结

虽然结果上没有提升,但是过程中有了一些进步,稳定提升中。

第1题:10分钟左右,还可以练练速度。

第2题:蒙圈了,尝试了一会儿发现思路不够清晰,就放弃了。

第3题:思路很快,变成很快,但是遇到了内存的坑,卡住了很久,不过能调出来还挺开心的。

第4题:不难,但当时思路很乱,如果能多一点冷静分析结果应该会更好。

优点

1.心态更好了。

2.在容器选择上更加熟练了。

3.简单题速度更快了。

4.代码写的更熟练了,低级错误减少。

缺点&改进

1.对代码的复杂度分析不够:比如不容器的时/空复杂度。第3题中同样储存2个变量的效果,vector在递归中导致stack_overflow,换成pair后通过。这边在后续加一个总结。

2.代码冷检查不够:写完后重新肉眼观察代码,耐心不够。平时练习中继续训练。

3.DP和递归的不够熟练,树的较难题不熟。这个在刷完一遍题之后刷难题来加强

4.在紧张的时间下,代码设计不够优雅。

 

题目

1.【easy】5336. Increasing Decreasing String

Given a string s. You should re-order the string using the following algorithm:

  1. Pick the smallest character from s and append it to the result.
  2. Pick the smallest character from s which is greater than the last appended character to the result and append it.
  3. Repeat step 2 until you cannot pick more characters.
  4. Pick the largest character from s and append it to the result.
  5. Pick the largest character from s which is smaller than the last appended character to the result and append it.
  6. Repeat step 5 until you cannot pick more characters.
  7. Repeat the steps from 1 to 6 until you pick all characters from s.

In each step, If the smallest or the largest character appears more than once you can choose any occurrence and append it to the result.

Return the result string after sorting s with this algorithm.

Example 1:

Input: s = "aaaabbbbcccc"
Output: "abccbaabccba"
Explanation: After steps 1, 2 and 3 of the first iteration, result = "abc"
After steps 4, 5 and 6 of the first iteration, result = "abccba"
First iteration is done. Now s = "aabbcc" and we go back to step 1
After steps 1, 2 and 3 of the second iteration, result = "abccbaabc"
After steps 4, 5 and 6 of the second iteration, result = "abccbaabccba"

Example 2:

Input: s = "rat"
Output: "art"
Explanation: The word "rat" becomes "art" after re-ordering it with the mentioned algorithm.

Example 3:

Input: s = "leetcode"
Output: "cdelotee"

Example 4:

Input: s = "ggggggg"
Output: "ggggggg"

Example 5:

Input: s = "spo"
Output: "ops"

Constraints:

  • 1 <= s.length <= 500
  • s contains only lower-case English letters.

题目链接:https://leetcode-cn.com/problems/increasing-decreasing-string/

思路

借助map对string的字符和出现个数进行记录,通过正反遍历来实现题目要求的效果。

class Solution {
public:
    string sortString(string s) {
        int len = s.size();
        if(len==0) return "";
        map<char, int> rec;
        string res;
        for(int i=0; i<len; ++i){
            ++rec[s[i]];
        }
        while(res.size()<len){
            for(auto iter=rec.begin(); iter!=rec.end() && res.size()<len; ++iter){
                if(iter->second>0) {
                    res+=(iter->first);
                    --(iter->second);
                }
            }
            if(res.size()>=len) break;
            for(auto iter=rec.rbegin(); iter!=rec.rend() && res.size()<len; ++iter){
                if(iter->second>0){
                    res+=(iter->first);
                    --(iter->second);
                }
            }
        }
        return res;
    }
};

 

2.【medium】1371. Find the Longest Substring Containing Vowels in Even Counts

Given the string s, return the size of the longest substring containing each vowel an even number of times. That is, 'a', 'e', 'i', 'o', and 'u' must appear an even number of times.

Example 1:

Input: s = "eleetminicoworoep"
Output: 13
Explanation: The longest substring is "leetminicowor" which contains two each of the vowels: e, i and o and zero of the vowels: a and u.

Example 2:

Input: s = "leetcodeisgreat"
Output: 5
Explanation: The longest substring is "leetc" which contains two e's.

Example 3:

Input: s = "bcbcbc"
Output: 6
Explanation: In this case, the given string "bcbcbc" is the longest because all vowels: a, e, i, o and u appear zero times.

Constraints:

  • 1 <= s.length <= 5 x 10^5
  • s contains only lowercase English letters.

题目链接:https://leetcode-cn.com/problems/find-the-longest-substring-containing-vowels-in-even-counts/

思路

难点:

1)如何使用DP:能够想到题目和DP有关,但如何记录中间结果,能起到对后面步骤起到作用,这个比较难想到。

2)如何同时表达5个标志的状态:题目要求对5个元音字母的奇偶个数做记录,从1个判等式变为了5个,可以联想到用位运算来记录当前状态,状态有32个:0~31。

突破口:

如果子串[0,i]的状态和子串[0,j]一样,那么子串[i+1,j]一定满足要求。

DP的表达:

需要对每一种状态记录它们最早出现的位置,当后面再出现同样状态时,就可以得到一个满足要求的子串,再每次遇到满足的子串是记下最长的即可。

class Solution {
public:
    int findTheLongestSubstring(string s) {
        int len = s.size();
        if(len==0) return 0;
        int res = 0, now = 0;
        int stat[32];
        memset(stat, -2, 32*sizeof(int));
        stat[0] = -1;
        for(int i=0; i<len; ++i){
            switch (s[i]){
                case 'a':{
                    now ^= 1;
                    break;
                }
                case 'e':{
                    now ^= 2;
                    break;
                }
                case 'i':{
                    now ^= 4;
                    break;
                }
                case 'o':{
                    now ^= 8;
                    break;
                }
                case 'u':{
                    now ^= 16;
                    break;
                }
                default:{
                    break;
                }
            }
            if (stat[now]>-2){
                res = max(i-stat[now], res);
            }else{
                stat[now] = i;
            }
        }
        return res;
    }
};

 

3.【medium】1372. Longest ZigZag Path in a Binary Tree

Given a binary tree root, a ZigZag path for a binary tree is defined as follow:

  • Choose any node in the binary tree and a direction (right or left).
  • If the current direction is right then move to the right child of the current node otherwise move to the left child.
  • Change the direction from right to left or right to left.
  • Repeat the second and third step until you can't move in the tree.

Zigzag length is defined as the number of nodes visited - 1. (A single node has a length of 0).

Return the longest ZigZag path contained in that tree.

Example 1:

Input: root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1,null,1]
Output: 3
Explanation: Longest ZigZag path in blue nodes (right -> left -> right).

Example 2:

Input: root = [1,1,1,null,1,null,null,1,1,null,1]
Output: 4
Explanation: Longest ZigZag path in blue nodes (left -> right -> left -> right).

Example 3:

Input: root = [1]
Output: 0

Constraints:

  • Each tree has at most 50000 nodes..
  • Each node's value is between [1, 100].

题目链接:https://leetcode-cn.com/problems/longest-zigzag-path-in-a-binary-tree/

思路

很容易想到用递归的方法。

每层递归考虑:子串满足要求,判断当前层能否满足要求,并更新最大结果的记录。

再多注意一下边界条件即可。

!这里有一个c++编程的坑:同样是记录2个int,vector使用空间大于pair,递归次数很大时,vector可能导致stack_overflow。所以能用pair就pair。

/**
 * 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 maxv = 0;
    int longestZigZag(TreeNode* root) {
        if(!root) return 0;
        trace(root);
        return maxv;
    }
    pair<int,int> trace(TreeNode* root){
        pair<int,int> res;
        if(!root) return res;
        if(!root->left && !root->right) return make_pair(0,0);
        pair<int,int> l, r;
        l = trace(root->left);
        r = trace(root->right);
        res = make_pair(((root->left)?l.second+1:0), ((root->right)?r.first+1:0));
        maxv = max(maxv, max(res.first, res.second));
        return res;
    }
};

 

4.【hard】1373. Maximum Sum BST in Binary Tree

Given a binary tree root, the task is to return the maximum sum of all keys of any sub-tree which is also a Binary Search Tree (BST).

Assume a BST is defined as follows:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than the node's key.
  • Both the left and right subtrees must also be binary search trees.

Example 1:

Input: root = [1,4,3,2,4,2,5,null,null,null,null,null,null,4,6]
Output: 20
Explanation: Maximum sum in a valid Binary search tree is obtained in root node with key equal to 3.

Example 2:

Input: root = [4,3,null,1,2]
Output: 2
Explanation: Maximum sum in a valid Binary search tree is obtained in a single root node with key equal to 2.

Example 3:

Input: root = [-4,-2,-5]
Output: 0
Explanation: All values are negatives. Return an empty BST.

Example 4:

Input: root = [2,1,3]
Output: 6

Example 5:

Input: root = [5,4,8,3,null,6,3]
Output: 7

Constraints:

  • Each tree has at most 40000 nodes..
  • Each node's value is between [-4 * 10^4 , 4 * 10^4].

题目链接:https://leetcode-cn.com/problems/maximum-sum-bst-in-binary-tree/

思路

错误思路:自底向上传递结果,约束条件自顶向下传递。

错误原因:在判断下层子树是否BST时,不需要有上层约束,而到了上层才需要判断子树的最大最小值是否还在范围内。

样例:

[4,8,null,6,1,9,null,-5,4,null,null,null,-3,null,10]

正确思路:向上返回的内容需要包括以下内容,

1)子树是否BST;

2)子树的和;

3)子树的最大最小值。

在上层来判断当前为根节点是否能成为BST,能则需要更新记录。

/**
 * 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 res;
    int maxSumBST(TreeNode* root) {
        if(!root) return 0;
        res = 0;
        trace(root);
        return res;
    }
    vector<int> trace(TreeNode* root){
        if(!root) return {0};
        auto ltree = trace(root->left);
        auto rtree = trace(root->right);
        if(ltree[0]>INT_MIN && rtree[0]>INT_MIN){
            int l = 0, r = 0, m = root->val;
            if(root->left && ltree.size()>1){
                l = root->left->val;
                if(l>=m ||ltree[2]>=m){
                    return {INT_MIN};
                }
            }
            if(root->right && rtree.size()>1){
                r = root->right->val;
                if(m>=r || m>=rtree[1]){
                    return {INT_MIN};
                }
            }
            int sum = ltree[0] + rtree[0] + m;
            res = max(res, sum);
            int vmin = (ltree.size()>1)?ltree[1]:m;
            int vmax = (rtree.size()>1)?rtree[2]:m;
            return {sum, vmin, vmax};
        }
        return {INT_MIN};
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值