leetcode-2097:合法重新排列数对

简介: leetcode-2097:合法重新排列数对

题目

题目链接

给你一个下标从 0 开始的二维整数数组 pairs ,其中 pairs[i] = [starti, endi] 。如果 pairs 的一个重新排列,满足对每一个下标 i ( 1 <= i < pairs.length )都有 endi-1 == starti ,那么我们就认为这个重新排列是 pairs 的一个 合法重新排列 。

请你返回 任意一个 pairs 的合法重新排列。

注意:数据保证至少存在一个 pairs 的合法重新排列。

示例 1:

输入:pairs = [[5,1],[4,5],[11,9],[9,4]]
输出:[[11,9],[9,4],[4,5],[5,1]]
解释:
输出的是一个合法重新排列,因为每一个 endi-1 都等于 starti 。
end0 = 9 == 9 = start1 
end1 = 4 == 4 = start2
end2 = 5 == 5 = start3

示例 2:

输入:pairs = [[1,3],[3,2],[2,1]]
输出:[[1,3],[3,2],[2,1]]
解释:
输出的是一个合法重新排列,因为每一个 endi-1 都等于 starti 。
end0 = 3 == 3 = start1
end1 = 2 == 2 = start2
重新排列后的数组 [[2,1],[1,3],[3,2]] 和 [[3,2],[2,1],[1,3]] 都是合法的。

示例 3:

输入:pairs = [[1,2],[1,3],[2,1]]
输出:[[1,2],[2,1],[1,3]]
解释:
输出的是一个合法重新排列,因为每一个 endi-1 都等于 starti 。
end0 = 2 == 2 = start1
end1 = 1 == 1 = start2

解题

方法一:回溯(超时)

使用和leetcode-332:重新安排行程类似的方式,进行暴力回溯,但是超时了。

class Solution {
public:
    unordered_map<int,map<vector<int>,int>> targets;
    bool backtracing(int k,vector<vector<int>>& res){
        if(res.size()==k){
            return true;
        }
        for(pair<const vector<int>,int>& target:targets[res.back()[1]]){
            if(target.second>0){
                res.push_back(target.first);
                target.second--;
                if(backtracing(k,res)) return true;
                target.second++;
                res.pop_back();
            }
        }
        return false;
    }
    vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
        vector<vector<int>> res;
        for(const vector<int>& vec:pairs){
            targets[vec[0]][vec]++;
        }
        for(vector<int>& vec:pairs){
            res.push_back(vec);
            targets[vec[0]][vec]--;
            if(backtracing(pairs.size(),res)) break;
            targets[vec[0]][vec]++;
            res.pop_back();
        }
        return res;
    }
};

方法二:欧拉路径问题(Hierholzer 算法)

参考链接

参考链接

无向图中,度指的是一个顶点有多少关联的边

有向图中,度可以分为入度和出度

这道题是一道有向图

因为每一条线都是有方向的,所以称之为有向图

直接记录边

class Solution {
public:
    unordered_map<int,vector<int>> map;
    unordered_map<int,int> deg;
    vector<vector<int>> res;
    void dfs(int curr){
        while(map.count(curr)&&!map[curr].empty()){
            int tmp=map[curr].back();
            map[curr].pop_back();
            dfs(tmp);
            res.push_back({curr,tmp});
        }
    }
    vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
        for(vector<int>& pair:pairs){
            map[pair[0]].push_back(pair[1]);
            deg[pair[0]]--,deg[pair[1]]++;
        }
        for(auto it=deg.begin();it!=deg.end();it++) if(it->second==-1) dfs(it->first);
        if(res.empty()) dfs(deg.begin()->first);
        reverse(res.begin(),res.end());
        return res;
    }
};

同样可以记录节点

class Solution {
public:
    unordered_map<int,vector<int>> map;
    unordered_map<int,int> deg;
    vector<int> res;
    void dfs(int curr){
        while(map.count(curr)&&!map[curr].empty()){
            int tmp=map[curr].back();
            map[curr].pop_back();
            dfs(tmp);
        }
        res.push_back(curr);
    }
    vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
        for(vector<int>& pair:pairs){
            map[pair[0]].push_back(pair[1]);
            deg[pair[0]]--,deg[pair[1]]++;
        }
        for(auto it=deg.begin();it!=deg.end();it++) if(it->second==-1) dfs(it->first);
        if(res.empty()) dfs(deg.begin()->first);
        reverse(res.begin(),res.end());
        vector<vector<int>> ans;
        for(int i=1;i<res.size();i++){
            ans.push_back({res[i-1],res[i]});
        }
        return ans;
    }
};


相关文章
|
7月前
|
测试技术
leetcode-1592:重新排列单词间的空格
leetcode-1592:重新排列单词间的空格
48 0
【Leetcode -441.排列硬币 -448.找到所有数组中消失的数字】
【Leetcode -441.排列硬币 -448.找到所有数组中消失的数字】
43 0
|
程序员
【Leetcode】面试题 01.02. 判定是否互为字符重排、面试题 01.04. 回文排列
目录 面试题 01.02. 判定是否互为字符重排 面试题 01.04. 回文排列
62 0
|
2月前
|
算法 C++ 容器
Leetcode第三十一题(下一个排列)
这篇文章介绍了LeetCode第31题“下一个排列”的C++解决方案,该算法通过原地修改数组来找到下一个字典序更大的排列,如果不存在则重排为字典序最小的排列。
33 0
Leetcode第三十一题(下一个排列)
|
6月前
|
存储 算法 数据挖掘
python 数学+减治、下一个排列法、DFS回溯法实现:第 k 个排列【LeetCode 题目 60】
python 数学+减治、下一个排列法、DFS回溯法实现:第 k 个排列【LeetCode 题目 60】
|
4月前
|
算法 Java
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
56 0
|
6月前
|
算法
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
|
6月前
|
算法
【经典LeetCode算法题目专栏分类】【第2期】组合与排列问题系列
【经典LeetCode算法题目专栏分类】【第2期】组合与排列问题系列
|
6月前
|
存储 算法 数据挖掘
LeetCode 题目 31:下一个排列【python】
LeetCode 题目 31:下一个排列【python】
|
7月前
|
容器
leetcode-31:下一个排列
leetcode-31:下一个排列
53 1