返回顶部

LeetCode第270场周赛

T1 5942. 找出 3 位偶数

题目描述:
给你一些数字,找出所有使用其中任意三个数字组成的不含前导\(0\)的偶数。
思路:
考虑到数字个数很少,直接暴力三重循环然后用\(map\)判重并统计答案即可,注意最后要对答案数组进行排序。
时间复杂度:\(O(n^3)\)
参考代码:

class Solution {
public:
    vector<int> findEvenNumbers(vector<int>& digits) {
        vector<int> res;
        map<int, int>mp;
        int n = digits.size();
        for(int i = 0 ; i < n ; ++i)
            for(int j = 0 ; j < n ; ++j)
                for(int k = 0 ; k < n ; ++k){
                    if(i == j || i == k || j == k) continue;
                    if(digits[i] == 0) continue;
                    int dx = digits[i] * 100 + digits[j] * 10 + digits[k];
                    if(dx & 1) continue;
                    if(mp.count(dx)) continue;
                    res.push_back(dx);
                    mp[dx] = 1;
                }
        sort(res.begin(), res.end());
        return res;
    }
};

T2 5943. 删除链表的中间节点

题目描述:
删除链表的中间节点,中间节点的定义为位于链表\(\llcorner \frac{n}{2} \lrcorner\)处的节点(\(n\)为链表节点的数量)
思路:
先统计出链表节点的数量,然后根据题意删除即可
时间复杂度:\(O(n)\)
参考代码:

class Solution {
public:
    ListNode* deleteMiddle(ListNode* head) {
        int cnt = 0;
        ListNode* p = head;
        while(p != nullptr){
            ++cnt;
            p = p->next;
        }
        if(cnt == 1) return nullptr;
        cnt >>= 1;
        cnt--;
        p = head;
        while(cnt > 0){
            --cnt;
            p = p->next;
        }
        p->next = p->next->next;
        return head;
    }
};

T3 5944. 从二叉树一个节点到另一个节点每一步的方向

题目描述:
给你一个二叉树,每个节点有一个\(val\),节点的\(val\)两两不同,然后给你起点和终点,让你输出从起点到终点的行走方式
思路:
考虑第一遍\(dfs\)将每个节点的父结点预处理出来,然后第二遍\(dfs\)将起点所对应的节点找到,第三遍\(dfs\)以起点为根进行搜索求解,注意过程中标记访问和进行答案的记录
时间复杂度:\(O(n)\)
参考代码:

class Solution {
private:
    void dfs(TreeNode* root , TreeNode* father , vector<TreeNode*>& fa){
        if(root == nullptr) return ;
        fa[root->val] = father;
        dfs(root->left , root , fa);
        dfs(root->right , root , fa);
        return ;
    }
    TreeNode* dfs1(TreeNode* root , int val){
        if(root == nullptr) return nullptr;
        if(root->val == val) return root;
        TreeNode* left = dfs1(root->left , val);
        if(left != nullptr) return left;
        return dfs1(root->right , val);
    }
    string res;
    bool flag;
    void dfs(TreeNode* root ,  int val, vector<int>& vis , vector<TreeNode*>& fa){
        if(root == nullptr || vis[root->val]) return ;
        if(root->val == val) flag = true;
        if(flag) return ;
        vis[root->val] = 1;
        res += 'L';
        dfs(root->left , val, vis , fa);
        if(flag) return ;
        res.pop_back();
        res += 'R';
        dfs(root->right , val , vis , fa);
        if(flag) return ;
        res.pop_back();
        res += 'U';
        dfs(fa[root->val], val , vis , fa);
        if(flag) return ;
        res.pop_back();
        return ;
    }
public:
    string getDirections(TreeNode* root, int startValue, int destValue) {
        vector<TreeNode*> fa =  vector<TreeNode*>(100005 , nullptr);
        vector<int> vis = vector<int>(100005 , 0);
        dfs(root , nullptr , fa);
        TreeNode* start = dfs1(root , startValue);
        dfs(start , destValue , vis , fa);
        return res;
    }
};

T4 5932. 合法重新排列数对

题目描述:
给你\(n\)个二元组\([start , end]\),让你重新排列这些二元组使得对于任意的\(1 \leq i < n\),满足\(end_{i - 1} = start_i\)
思路:
比较明显的求欧拉路径的题目。由于二元组中的值比较大,所以先进行离散化处理,然后建立相应的单向边,由于题目保证有解,所以我们在建好图后,根据欧拉路径的判定定理,以及这题是单向边,所以找到入度-出度为\(1\)(如果存在)的点或者任选一个点(前一种点不存在)作为起点,然后进行\(dfs\)并记录相应的路径即可,最后将路径倒置并转换成相应的二元组即为所求。注意到求解过程中需要删除边,所以使用multiset存图。
时间复杂度: \(O(nlogn)\)
参考代码:

class Solution {
private:
    void dfs(vector<multiset<int>>& graph, int u, vector<int>& path) {
        for (auto v = graph[u].begin(); v != graph[u].end(); v = graph[u].begin()) {
            int val = *v;
            graph[u].erase(v);
            dfs(graph, val, path);
        }
        path.push_back(u);
    }
public:
    vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
        vector<int>a;
        for (auto p : pairs) a.push_back(p[0]), a.push_back(p[1]);
        sort(a.begin(), a.end());
        int tot = unique(a.begin(), a.end()) - a.begin();
        unordered_map<int, int> mp;
        int idx = 0;
        for (int i = 0; i < tot; ++i) mp[a[i]] = ++idx;
        int n = tot + 5;
        vector<multiset<int>>graph(n + 1);
        vector<int> income(n + 1, 0);
        vector<int> outcome(n + 1, 0);
        for (auto p : pairs) {
            graph[mp[p[0]]].insert(mp[p[1]]);
            outcome[mp[p[0]]]++;
            income[mp[p[1]]]++;
        }
        int start = 1;
        for (int i = 1; i <= idx; ++i)
            if (outcome[i] - income[i] == 1) {
                start = i;
                break;
            }
        vector<int>path;
        dfs(graph, start, path);
        reverse(path.begin(), path.end());
        vector<vector<int>> res;
        int m = path.size();
        for (int i = 0; i < m - 1; ++i) {
            res.push_back({ a[path[i] - 1] , a[path[i + 1] - 1] });
        }
        return res;
    }
};

推荐题目:
P1333 瑞瑞的木棍
UVA10441 Catenyms
P7771 【模板】欧拉路径

posted @ 2021-12-05 22:50  cherish-lgb  阅读(22)  评论(0编辑  收藏  举报