Skip to content

Conversation

@InSange
Copy link
Collaborator

@InSange InSange commented Nov 30, 2024

πŸ”— 문제 링크

Valid Arrangement of Pairs

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

3μ‹œκ°„

✨ μˆ˜λ„ μ½”λ“œ

κ°œμš”

κ·Έλž˜ν”„ 문제둜 간선에 λŒ€ν•œ 정보듀을 2차원 λ°°μ—΄ ν˜•νƒœλ‘œ μ£Όμ–΄μ§„λ‹€.
Input: pairs = [[5,1],[4,5],[11,9],[9,4]]

첫 번째 λ…Έλ“œλŠ” μΆœλ°œμ§€κ³  두 번째 μš”μ†Œλ‘œ μ£Όμ–΄μ§€λŠ” λ…Έλ“œλŠ” 도착지이닀.
5 -> 1
4 -> 5
11 -> 9
9 -> 4

μ–΄λ–€ λ…Έλ“œμ—μ„œ μΆœλ°œμ„ ν•˜μ˜€μ„ λ•Œ ν•΄λ‹Ή 간선듀을 λͺ¨λ‘ μ΄μš©ν•˜μ—¬ μœ νš¨ν•œ κ·Έλž˜ν”„λ₯Ό λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.
즉, μ£Όμ–΄μ§„ pairs의 간선듀을 λͺ¨λ‘ μ‚¬μš©ν•΄μ„œ 각 λ…Έλ“œλ“€μ„ ν†΅κ³Όν•˜λŠ” μ—°μ†λœ 배열을 ν‘œν˜„ν•΄μ•Όν•¨.

μ€‘μš”ν•œ 점은 μ£Όμ–΄μ§€λŠ” 간선은 무쑰건 μœ νš¨ν•˜λ‹€λŠ” 점.
image
μ΄λ ‡κ²Œ 쀑간 λ…Έλ“œμ—μ„œ λ‹€λ₯Έ λ…Έλ“œλ‘œ κ°„ ν›„ λ‹€λ₯Έ 간선듀을 μ΄μš©ν•  수 μ—†λŠ” κ²½μš°κ°€ μ—†λ‹€.
image
μœ„μ˜ 예제둜 이런 μ‹μœΌλ‘œ λͺ¨λ“  간선듀을 ν™œμš©ν•΄μ„œ μœ νš¨ν•œ κ·Έλž˜ν”„λ₯Ό λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.

μ ‘κ·Ό 방식

무쑰건 μœ νš¨ν•˜λ‹€λŠ” μ μ—μ„œ λͺ¨λ“  간선듀을 λ‹€ μ΄μš©ν•  λ•Œ 두 κ°€μ§€μ˜ 경우λ₯Ό 생각할 수 μžˆλ‹€.

  1. μœ„μ˜ κ·Έλ¦Ό 처럼 λͺ¨λ“  λ…Έλ“œλ“€μ΄ λ™μΌν•˜κ²Œ ν•˜λ‚˜μ˜ κ°„μ„ μœΌλ‘œ 이어져 μžˆκ±°λ‚˜ N개의 κ°„μ„ μœΌλ‘œ 이어져 μžˆμ„ 경우.
  2. μ–΄λ–€ νŠΉμ •ν•œ λ…Έλ“œμ—μ„œ μ§„μΆœ 차수(OutDegree)κ°€ μ§„μž… 차수(InDegree)보닀 1 λ§Žμ„ 경우. 이 경우 ν•΄λ‹Ή λ…Έλ“œμ—μ„œ μΆœλ°œμ„ ν•΄μ£Όμ–΄μ•Ό 돌고 λŒμ•„ N번의 μ§„μž… 차수 만큼 λŒμ•˜μ„ λ•Œ λ‚˜λ¨Έμ§€ ν•œ 경둜λ₯Ό 따라 갈 수 있기 λ•Œλ¬Έμ΄λ‹€.

Constraints:

1 <= pairs.length <= 10^5
pairs[i].length == 2
0 <= starti, endi <= 10^9
starti != endi
No two pairs are exactly the same.
There exists a valid arrangement of pairs.

μ£Όμ–΄μ§„ μ œμ•½ μ‘°κ±΄μ—μ„œ μš”μ†Œμ˜ 크기가 0μ—μ„œ 10^9이기에 일반적인 λ°°μ—΄λ‘œ 각 λ…Έλ“œμ— μ§„μΆœ, μ§„μž… 차수λ₯Ό κ΄€λ¦¬ν•˜κΈ°λŠ” μ–΄λ ΅λ‹€κ³  μƒκ°ν–ˆλ‹€.
unordered_mapμ—μ„œ 각 λ…Έλ“œμ˜ μ§„μΆœ λ…Έλ“œλ“€μ„ κ΄€λ¦¬ν•΄μ£ΌλŠ” μ‹μœΌλ‘œ κ²°μ •.
그럼 각 λ…Έλ“œλ“€μ—μ„œ μ£Όμ–΄μ§„ κ°„μ„  정보λ₯Ό λ°”νƒ•μœΌλ‘œ μ§„μΆœν•  경우. μ§„μΆœν•  λ…Έλ“œλ“€μ— λŒ€ν•œ 정보듀을 관리해주어야 ν•˜λŠ”λ° visit λ°°μ—΄λ‘œ κ΄€λ¦¬ν•΄μ£ΌκΈ°μ—λŠ” λ„ˆλ¬΄ 크기에 λ°©λ¬Έν•œ λ…Έλ“œλ“€μ„ 직접 μ œκ±°ν•΄μ£ΌλŠ” λ°©μ‹μœΌλ‘œ dequeλ₯Ό ν™œμš©ν•˜κΈ°λ‘œ ν–ˆλ‹€.
그리고 μΆœλ°œμ§€λ₯Ό μ •ν•˜κΈ°μœ„ν•΄ 각 μ§„μž…, μ§„μΆœ 차수λ₯Ό μ €μž₯해쀄 unordred_map을 μΆ”κ°€.

unordered_map<int, deque<int>> nodes; // n개의 λ…Έλ“œλ“€κ³Ό κ°„μ„ μœΌλ‘œ μ—°κ²°λœ λ…Έλ“œλ“€μ˜ 정보λ₯Ό 포함.
unordered_map<int, int> inDegree; // n개의 λ…Έλ“œλ“€λ‘œλΆ€ν„° μ§„μž… 차수
unordered_map<int, int> outDegree; // n개의 λ…Έλ“œλ“€λ‘œλΆ€ν„° μ§„μΆœμ°¨μˆ˜

λ…Έλ“œλ“€μ— λŒ€ν•œ 정보λ₯Ό μΆ”κ°€ν•΄μ£Όμ—ˆμœΌλ©΄ κ·Έλž˜ν”„ 탐색을 ν•΄μ£Όλ©΄ λœλ‹€.
μš°λ¦¬λŠ” 간선을 톡해 순차적으둜 λ…Έλ“œλ“€μ„ λ°©λ¬Έν•΄μ£Όλ©΄ λœλ‹€.
DFSλ₯Ό ν™œμš©ν•  κ²ƒμ΄λΌλŠ” κ³„νšκΉŒμ§€λŠ” μ’‹μ•˜μ§€λ§Œ 풀이가 μ‰½κ²Œ λ– μ˜€λ₯΄μ§€ μ•Šμ•„μ„œ λ‹€λ₯Έ 글을 μ°Έκ³ .

좜발 λ…Έλ“œλΆ€ν„° μ‹œμž‘ν•˜μ—¬ λ…Έλ“œμ™€ μ—°κ²°λœ λ…Έλ“œλ“€μ„ ν•˜λ‚˜μ”© 제거 ν•΄μ€€ λ’€ λ‹€μŒ λ…Έλ“œλ₯Ό νƒμƒ‰ν•œλ‹€.
그럼 κ²°κ΅­ λΉ„μ›Œμ ΈμžˆλŠ” λ…Έλ“œλ₯Ό λ°œκ²¬ν•˜κ²Œ 될 것이고.
ν•΄λ‹Ή λΉ„μ›Œμ ΈμžˆλŠ” λ…Έλ“œλŠ” μ΅œμ’… λ…Έλ“œκ°€ 될 것이닀. (κ°€μž₯ λ§ˆμ§€λ§‰μ— λ°©λ¬Έν•œ λ…Έλ“œμ΄κΈ°μ—)
κ·Έλ ‡κ²Œ μž¬κ·€λ₯Ό 톡해 λŒμ•„μ˜€λ‹€λ³΄λ©΄ 각각의 λ…Έλ“œλ“€μ΄ λΉ„μ›Œμ Έμžˆμ„ 것이고 λΉ„μ›Œμ ΈμžˆλŠ” λ…Έλ“œλ“€μ„ result 배열에 μ €μž₯ν•œλ‹€.

μ—¬κΈ°μ„œ μš°λ¦¬λŠ” κ°€μž₯ λ§ˆμ§€λ§‰μ— λ°©λ¬Έν•  λ…Έλ“œλΆ€ν„° μΆ”κ°€λ₯Ό ν•˜μ˜€κΈ°μ— result 배열에 λ§ˆμ§€λ§‰μœΌλ‘œ pushλ˜λŠ” λ…Έλ“œλŠ” μΆœλ°œμ§€μ μ΄ 될 것이닀.

각 λ…Έλ“œλ₯Ό 두 κ°œμ”© λ¬Άμ–΄ 거꾸둜 ans 2차원 배열에 λ„£μ–΄μ£Όλ©΄ 끝.

쀑간에
pairs = [[1,2],[1,3],[2,1]]
μœ„μ™€ 같이 μ£Όμ–΄μ‘Œμ„ λ•Œ
1->3을 λ¨Όμ € λ°©λ¬Έν–ˆμ„ λ•Œ μ–΄λ–»κ²Œ λ˜λŠ”κ±°μ§€ 의문이 λ“€μ—ˆμ—ˆλŠ”λ°
3을 λ¨Όμ € λ°©λ¬Έν•˜λ“  2λ₯Ό λ¨Όμ € λ°©λ¬Έν•˜λ“  간에 nodes[3]의 값은 λΉ„μ›Œμ ΈμžˆκΈ°μ— 무쑰건 result에 첫번째둜 λ°©λ¬Έν•˜κ²Œ 될 것 이닀.
2의 경우 λ‹€μ‹œ 1 λ…Έλ“œλ‘œ λŒμ•„μ˜€κΈ° λ•Œλ¬Έμ΄λ‹€.
result = [3, 1, 2, 1] 둜 될 것이닀.

μ†ŒμŠ€ μ½”λ“œ

class Solution {
public:
    unordered_map<int, deque<int>> nodes;
    unordered_map<int, int> inDegree;
    unordered_map<int, int> outDegree;
    
    vector<int> result;
    
    void DFS(int index)
    {
        while(!nodes[index].empty())
        {
            int nextNode = nodes[index].front();
            nodes[index].pop_front();
            DFS(nextNode);
        }
        result.push_back(index); // κ²°κ΅­. λͺ¨λ“  λ…Έλ“œλ“€μ„ λ°©λ¬Έν–ˆλ‹€λ©΄. 즉 λΉ„μ›Œμ ΈμžˆλŠ” λ…Έλ“œμ— λ°©λ¬Έν–ˆλ‹€λ©΄ 도착지 κ²½λ‘œκ°€ 거꾸둜 μ΄μ–΄μ§€κ²Œ 됨.
    }
    
    vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
        for(const vector<int>& pair : pairs)
        {
            int depart = pair[0];
            int dest = pair[1];
            
            nodes[depart].push_back(dest);
            inDegree[dest]++;
            outDegree[depart]++;
        }
        
        int startNode = -1;
        
        for(const auto& degree : outDegree)
        {
            int curNode = degree.first;
            if(outDegree[curNode] == inDegree[curNode] + 1) // ν˜„μž¬ λ…Έλ“œμ—μ„œ μΆœλ°œμ§€κ°€ ν˜„μž¬ λ…Έλ“œλ‘œ λ“€μ–΄μ˜€λŠ” μ§„μž…μ˜ 개수 + 1일 경우. 이 λ…Έλ“œλŠ” 돌고 λŒμ•„ λ‹€μ‹œ ν•΄λ‹Ή λ…Έλ“œλ₯Ό 거쳐야 λͺ¨λ“  λ…Έλ“œλ₯Ό λ°©λ¬Έν•  수 있음.
            {
                startNode = curNode;
                break;
            }
        }
        
        if(startNode == -1) // 좜발 λ…Έλ“œλ₯Ό 발견 λͺ»ν–ˆλ‹€λ©΄ λͺ¨λ“  λ…Έλ“œλŠ” 각각 ν•˜λ‚˜μ˜ μ§„μž…, μ§„μΆœμ§€λ₯Ό λ™μΌν•˜κ²Œ κ°€μ§€λŠ” 것
        {
            startNode = pairs[0][0];
        }
        
        DFS(startNode);
        
        vector<vector<int>> ans;
        for(int i = result.size() - 1; i > 0; i--)
        {
            ans.push_back({result[i], result[i-1]}); // μΆœλ°œμ§€μ™€ 도착지λ₯Ό 거꾸둜 λ³€κ²½
        }
        
        return ans;
    }
};

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

항상 μ˜ˆμ™Έμ‚¬ν•­μ„ μƒκ°ν•˜κ³  ν’€λ‹€λ³΄λ‹ˆ κ°„λ‹¨ν•œ λ¬Έμ œμ˜€μŒμ—λ„ 쑰금 였래걸렸던 것 κ°™λ‹€.

@InSange InSange self-assigned this Nov 30, 2024
@tgyuuAn tgyuuAn merged commit 856b1b0 into main Apr 30, 2025
1 check passed
@tgyuuAn tgyuuAn deleted the 31-Insange branch April 30, 2025 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants