LeetCode biweekly contest 21

本文深入解析了LeetCode上的三道经典算法题目,包括字符串排序、最长子串与二元树路径。通过递归与数据结构优化,实现了高效的时间与空间复杂度。适合所有热爱算法与数据结构的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RankNameScoreFinish TimeQ1 (4)Q2 (4)Q3 (5)Q4 (6)
175 / 4729YoungForest191:05:070:21:380:39:430:50:401:05:07

整体难度不大,尤其是后2题并没有该有的难度。

1370. Increasing Decreasing String

直接模拟构造结果字符串的过程即可。这里寻找字符串的过程可以使用二分查找,因为原始字符串需要更新,所以使用二叉查找树这一数据结构较好。

时间复杂度: O(N * log N),
空间复杂度: O(N).

class Solution {
public:
    string sortString(string s) {
        string ans;
        multiset<char> container;
        for (char c : s) {
            container.insert(c);
        }
        while (!container.empty()) {
            char smallest = *container.begin();
            container.erase(container.begin());
            ans.push_back(smallest);
            decltype(container.begin()) it;
            while ((it = container.upper_bound(smallest)) != container.end()) {
                ans.push_back(*it);
                smallest = *it;
                container.erase(it);
            }
            if (!container.empty()) {
                char largest = *(prev(container.end()));
                container.erase(prev(container.end()));
                ans.push_back(largest);
                while ((it = container.lower_bound(largest)) != container.begin()) {
                    ans.push_back(*prev(it));
                    largest = *prev(it);
                    container.erase(prev(it));
                }
            }
        }
        return ans;
    }
};

1371. Find the Longest Substring Containing Vowels in Even Counts

观察有:奇数减奇数等于偶数,偶数减偶数等于偶数。所以问题可以转化为,寻找最左边计数为奇数(或偶数)的位置。因为有5个元音字母,分奇偶,共32种状态。

时间复杂度: O(N),
空间复杂度: O(1).

class Solution {
public:
    int findTheLongestSubstring(string s) {
        vector<int> left_state(32, -2);
        left_state[0] = -1;
        auto code = [&](unordered_map<char, int>& m) -> unsigned int {
            const static vector<char> position = {'a', 'e', 'i', 'o', 'u'};
            unsigned  int ans = 0;
            for (unsigned  int i = 0; i < position.size(); ++i) {
                if  (m[position[i]] % 2 == 1) {
                    ans |= (1 << i);
                }
            }
            return ans;
        };
        unordered_map<char, int> m;
        int ans = 0;
        for (int i = 0; i < s.size(); ++i) {
            ++m[s[i]];
            auto c = code(m);
            if (left_state[c] != -2) {
                ans = max(ans, i - left_state[c]);
            } else {
                left_state[c] = i;
            }
        }
        return ans;
    }
};

1372. Longest ZigZag Path in a Binary Tree

树的问题用递归解。

时间复杂度: O(N),
空间复杂度: O(N).

/**
 * 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 {
    // left, right
    // return result if root is left/right child
    int ret = 0;
    pair<int, int> recurse(TreeNode* root) {
        if (root) {
            auto l = recurse(root->left);
            auto r = recurse(root->right);
            ret = max({ret, r.second + 1, l.first + 1});
            return {r.second + 1, l.first + 1};
        } else {
            return {-1, -1};
        }
    }
public:
    int longestZigZag(TreeNode* root) {
        auto ans = recurse(root);
        return ret;
    }
};

1373. Maximum Sum BST in Binary Tree

仍然是 树的问题用递归解决。
返回值依次为:

  • 子树中的最小值
  • 子树中的最大值
  • 是否为BST
  • 子树的和

时间复杂度: O(N),
空间复杂度: O(height).

/**
 * 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 {
    int ret = 0;
    // smallest, largest, BST?, sum
    tuple<int, int, bool, int> recurse(TreeNode* root) {
        if (!root) {
            return {0, 0, true, 0};
        } else {
            auto l = recurse(root->left);
            auto r = recurse(root->right);
            bool isBST = (root->left == nullptr || get<1>(l) < root->val) && (root->right == nullptr || get<0>(r) > root->val) && get<2>(l) && get<2>(r);
            int smallest = root->val, largest = root->val;
            if (root->left) {
                smallest = min(smallest, get<0>(l));
                largest = max(largest, get<1>(l));
            }
            if (root->right) {
                smallest = min(smallest, get<0>(r));
                largest = max(largest, get<1>(r));
            }
                   
            int s = get<3>(l) + get<3>(r) + root->val;
            if (isBST)
                ret = max(s, ret);
            return {smallest, largest, isBST, s};
        }
    }
public:
    int maxSumBST(TreeNode* root) {
        recurse(root);
        return ret;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值