루트 노드에서 리프 노드 및 sum-root-to-leaf-numbers 로의 경로
제목 설명
숫자 0-9 만 포함하는 이진 트리가 주어지면 루트 노드에서 리프 노드까지의 각 경로를 숫자로 나타낼 수 있습니다.
예를 들어 루트 노드에서 리프 노드로의 경로는 1-> 2-> 3이면이 경로는 123으로 바뀝니다.
루트 노드에서 리프 노드까지의 모든 경로가 나타내는 숫자의 합을 찾습니다.
예 :
1↵ / ↵ 2 3
루트 노드에서 리프 노드로
의 경로 1-> 2 루트 노드에서 다음으로의 경로를 바꿉니다 . 숫자 12 의 리프 노드 1-> 3 숫자 13이 바뀌
므로 답은 12 + 13 = 25입니다.
0-9의 숫자 만 포함하는 이진 트리가 주어지면 각 루트-리프 경로는 숫자를 나타낼 수 있습니다.
예는 숫자 123을 나타내는 루트에서 리프 경로 1-> 2-> 3입니다.
모든 루트에서 리프 숫자의 총합을 찾으십시오.
예 : 1↵
/ ↵ 2 3
루트에서 리프 경로 1-> 2는 숫자 12를 나타냅니다.
루트에서 리프 경로 1-> 3은 숫자 13을 나타냅니다.
합계 = 12 + 13 = 25를 반환합니다.
예
예 1
입력
{1,0}
산출
10
예제 2
입력
{1, #, 5}
산출
15
문제 해결 아이디어
아이디어 1 : BFS
- BFS에 따라 모든 리프 노드에서 루트 노드까지의 경로를 찾은 다음 추가합니다.
- mp를 사용하여 모든 하위-> 부모의 매핑을 기록합니다. 이는 통합 검색 집합과 유사하므로 리프 노드에서 루트 노드로 이동할 수 있습니다.
- 참고 : 상위에 여러 하위가있을 수 있고 매핑이 고유해야하므로 상위-> 하위 매핑을 생성 할 수 없습니다. 따라서 하위에서 상위로의 일대일 만 가능합니다.
- leafNode 배열을 사용하여 모든 리프 노드를 저장하고 마지막으로 mp 매핑을 사용하여 각 리프 노드의 경로 합계를 찾고 누적합니다.
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
#include "unordered_map"
class Solution {
public:
int sumNumbers(TreeNode* root) {
if(root == NULL) return 0;
int res(0);
queue<TreeNode*> myque;
myque.push(root);
//用于保存从叶节点到根节点的路径
unordered_map<TreeNode*, TreeNode*> mp;
mp[root] = root;
//用于保存所有的叶节点,方便遍历mp
vector<TreeNode*> leafNode;
while(!myque.empty()) {
int size = myque.size();
for(int i = 0; i < size; i ++) {
TreeNode* temp = myque.front();
myque.pop();
//如果左右子树均为空,则添加进leafnode中
if(!temp -> left && !temp -> right) {
leafNode.push_back(temp);
}
//如果有左右孩子,则添加 孩子->双亲 的映射
if(temp -> left) {
myque.push(temp -> left);
mp[temp -> left] = temp;
}
if(temp -> right) {
myque.push(temp -> right);
mp[temp -> right] = temp;
}
}
}
//对每一个叶节点都计算其路径和,并累加
for(auto node : leafNode) {
int sum(0); //记录每一个叶节点的路径和
int temp(1);
while(node != root) {
sum += node -> val * temp;
temp *= 10;
node = mp[node]; //不断往根节点遍历
}
sum += root -> val * temp; //最后加上根节点
res += sum;
}
return res;
}
};
아이디어 2 : 역 추적
- 경로 : 트랙에 기록
- 선택 목록 : 비어 있지 않은 왼쪽 및 오른쪽 하위 트리
- 종료 조건 : 리프 노드에 도달 한 다음 누적
- 참고 : 역 추적 방법이 트리의 경로 문제를 해결하기 전에 루트 노드를 경로에 추가해야합니다.
- 보충, 누적 기능 사용 :
-
accumulate의 헤더 파일은 다음과 같습니다.
#include <numeric>
-
예를 들어
vector<int> vec
배열의 경우 합계 :
int sum = accumulate(vec.begin(), vec.end(), 0)
누적 및 합계의 결과가 합계에 저장됩니다. 처음 두 매개 변수는 합계의 범위를 지정하고 세 번째 매개 변수는 누적의 초기 값을 지정합니다.accumulate를 사용하여 문자열 유형 벡터 컨테이너의 요소를 연결할 수도 있습니다.
string sum = accumulate(v.begin() , v.end() , string(" "));
이 함수 호출의 효과는 다음과 같습니다. 빈 문자열에서 시작하여 vec의 각 요소가 문자열에 연결됩니다.
-
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
#include<numeric>
class Solution {
public:
int sumNumbers(TreeNode* root) {
if(root == NULL) return 0;
int res(0);
vector<int> track;
//先把根节点添加进路径
track.push_back(root -> val);
backtrack(root, track, res);
return res;
}
void backtrack(TreeNode* root, vector<int>& track, int& res) {
if(root == NULL) return ;
//叶子节点,则累加
if(!root -> left && !root -> right) {
int sum(0); //对于每一个叶节点,记录其路径和
for(int i = 0; i < track.size(); i ++) {
sum = sum * 10 + track[i];
}
res += sum;
}
if(root -> left) {
track.push_back(root -> left -> val);
backtrack(root -> left, track, res);
track.pop_back();
}
if(root -> right) {
track.push_back(root -> right -> val);
backtrack(root -> right, track, res);
track.pop_back();
}
}
};
아이디어 3 : DFS
- DFS와 역 추적은 DFS가 업데이트 된 매개 변수를 다음 단계로 직접 가져온다는 점을 제외하면 비슷한 방식으로 작성됩니다. 역 추적은 먼저 업데이트 한 다음 철회하는 것이지만 둘 다 선택하는 것입니다.
- DFS는 역 추적과 동일하며 트리의 경로와 문제에 직면했을 때 먼저 결과에 루트 노드를 추가해야합니다.
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
#include<numeric>
class Solution {
public:
int sumNumbers(TreeNode* root) {
if(root == NULL) return 0;
int res = 0; //用于保存最终结果
int sum = root -> val; //用于记录每个叶节点的路径和,初始为根节点的值
dfs(root, res, sum);
return res;
}
void dfs(TreeNode* root, int& res, int sum) {
if(root == NULL) return ;
//如果是叶节点,则累加
if(!root -> left && !root -> right) {
res += sum;
}
//两个选择:左子树和右子树
if(root -> left) {
dfs(root -> left, res, sum * 10 + root -> left -> val);
}
if(root -> right) {
dfs(root -> right, res, sum * 10 + root -> right -> val);
}
}
};