2096. Step-By-Step Directions From a Binary Tree Node to Another / c++ / Medium / 30분
문제 및 코드
문제 링크
문제 코드
class Solution {
bool FindNode(TreeNode* current, int findValue, string& path)
{
if (current == nullptr) return false;
if (current->val == findValue) return true;
else if (FindNode(current->left, findValue, path))
{
path.push_back('L');
return true;
}
else if (FindNode(current->right, findValue, path))
{
path.push_back('R');
return true;
}
return false;
}
public:
string getDirections(TreeNode* root, int startValue, int destValue) {
// 1.두 경로를 찾는다.
// 1. root 에서 startValue까지의 경로
string rootToStart = "";
FindNode(root, startValue, rootToStart);
// 2. root 에서 destValue까지의 경로
string rootToDest = "";
FindNode(root, destValue, rootToDest);
// 2. 두 경로 중 겹치는 부분을 찾아서 지운다.
while (rootToStart.length() > 0 && rootToDest.length() > 0)
{
if (rootToStart.back() == rootToDest.back())
{
rootToStart.pop_back();
rootToDest.pop_back();
}
else break;
}
// 3. 1-1 (시작 노드에서 공통 부모 노드까지의)경로를 U로 대체
for (int i = 0; i < rootToStart.length(); ++i)
{
rootToStart[i] = 'U';
}
// 4. 1-1과 1-2를 붙인다.
reverse(rootToDest.begin(), rootToDest.end());
string result = rootToStart + rootToDest;
// 7. 6의 경로를 반환
return result;
}
};
접근 방식
자료구조 / 트리 / 문자열
- 트리의 시작 노드로부터 목적 노드까지의 최단 경로를 반환하는 문제
- 우선 경로는 시작 노드 -> 공통 부모 노드 -> 목적 노드 라고 가정했다.
- 2번을 만들기 위해서 아래의 두 경로를 구했다.
- 루트 노드에서 시작 노드까지의 경로
- 루트 노드에서 목적 노드까지의 경로
- 공통 부모를 알기 위해서 3-1, 3-2의 두 노드에서 겹치는 부분(루트 노드에서 공통 부모 노드까지의 경로)을 제거했다.
- 그 다음 3-1(공통 부모로부터 시작 노드까지의 경로)의 모든 원소를 U로 대체했다. (시작 노드에서 공통 부모 노드로의 경로이므로, 방향을 반대로 전환)
- 루트노드에서 특정 노드까지의 경로를 구할 때, 역순으로 구했기 때문에, 3-2를 뒤집어줬다.
- 5와 6의 경로를 더해서 반환.
- 해결
생각해 볼 점
- 트리 구조에서 시작 노드로부터 목적 노드까지의 최단 경로는 공통 부모 노드를 경유한다는 점은 빨리 생각해 낼 수 있었다.
- 루트 노드에서 특정 노드로의 경로를 구하는 부분을 고민했었는데, 일단 트리 순회가 필요하다고 생각해서 전위 순회(PreOrder-Traversal)로 구현했다.
- 그런데 해당 경로에 특정 노드가 존재하는지를 파악하기 위해 bool값도 반환이 필요했고, 만약 존재한다면 경로를 string으로도 기록해야했다.
- 그래서 반환값은 bool로 두고, string을 참조로 넘겨서 만약 경로 상에 찾고자 하는 노드가 존재한다면, path에 경로를 기록하는 식으로 구현했다. (이 때 구현의 용이성을 위해 path의 뒤에 추가하고 넘겨주는 식으로 구현했는데, 이로 인해 결과값은 뒤집힌 경로가 나왔다.)
- 트리와 트리 순회를 다시금 되짚을 수 있는 재밌는 문제였다.