1. 이진 트리에 따라 문자열 버튼을 만듭니다.
이진 트리의 루트 노드 루트가 주어지면 선주문 순회 방법을 사용하여 이진 트리를 대괄호와 정수로 구성된 문자열로 변환하고 구성된 문자열을 반환하십시오.
빈 노드는 빈 괄호 쌍 "()"으로 표시됩니다. 변환 후 문자열과 원래 이진 트리 간의 일대일 매핑에 영향을 주지 않는 모든 빈 괄호 쌍은 생략되어야 합니다.
출처: LeetCode
class Solution {
public:
string tree2str(TreeNode* root)
{
//根据前序遍历确定字符串
if(root==nullptr)
return "";
string tree=to_string(root->val);
//只有左右子树都为空不保留括号,其他情况都保留括号
if(root->left||root->right)
{
tree+='(';
tree+=tree2str(root->left);
tree+=')';
}
if(root->right)
{
tree+='(';
tree+=tree2str(root->right);
tree+=')';
}
return tree;
}
};
2. 이진 트리 계층 순회
이진 트리의 루트 노드가 주어지면
root
해당 노드 값의 레벨 순서 순회를 반환합니다 . (즉, 레이어별로, 왼쪽에서 오른쪽으로 모든 노드를 방문합니다).예시 1:
입력: 루트 = [3,9,20,null,null,15,7]
출력: [[3],[9,20],[15,7]]예시 2:
입력: 루트 = [1]
출력: [[1]]예시 3:
입력: 루트 = []
출력: []출처: LeetCode
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
//用队列来确定
queue<TreeNode*> TreeNode1;
vector<vector<int>> vv;
int levesize=0;
if(root)
{
TreeNode1.push(root);
levesize=1;
}
while(!TreeNode1.empty())
{
vector<int> v;
for(int i=0;i<levesize;i++)
{
TreeNode* front= TreeNode1.front();
TreeNode1.pop();
v.push_back(front->val);
if(front->left)
{
TreeNode1.push(front->left);
}
if(front->right)
{
TreeNode1.push(front->right);
}
}
vv.push_back(v);
//TreeNode.pop();
levesize=TreeNode1.size();
}
return vv;
}
};
이진 트리가 주어지면 트리에서 지정된 두 노드의 가장 가까운 공통 조상을 찾습니다.
바이두 백과사전에서 가장 가까운 공통 조상에 대한 정의는 다음과 같습니다. "뿌리 트리 T의 두 노드 p와 q에 대해 가장 가까운 공통 조상은 노드 x로 표현되며, x는 p와 q의 조상이고 깊이는 x는 가능한 한 큽니다. (A 노드는 자신의 조상이 될 수도 있습니다.)
예시 1:
입력: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
출력: 3
설명: 노드 5와 노드 1의 가장 가까운 공통 조상 노드 3입니다.예시 2:
입력: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
출력: 5
설명: 노드 5와 4의 가장 가까운 공통 조상은 다음과 같습니다. 노드 5. 정의에 따르면 가장 가까운 공통 조상 노드는 노드 자체가 될 수 있습니다.예시 3:
입력: root = [1,2], p = 1, q = 2
출력: 1출처: LeetCode
class Solution {
public:
bool find_node(TreeNode* root, TreeNode* p, stack<TreeNode*>& path)
{
if(root==nullptr)
return false;
path.push(root);
if (root == p)
return true;
if( find_node(root->left, p, path))
return true;
if( find_node(root->right, p, path))
return true;
path.pop();
return false;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
{
//使用两个栈存放二叉树要找的数据,
stack<TreeNode*> ppath;
stack<TreeNode*> qpath;
find_node(root, p, ppath);
find_node(root, q, qpath);
//确定长度
while (ppath.size() > qpath.size())
{
ppath.pop();
}
while (ppath.size() < qpath.size())
{
qpath.pop();
}
while (ppath.size() == qpath.size())
{
if (ppath.top() == qpath.top())
{
return ppath.top();
}
ppath.pop();
qpath.pop();
}
return nullptr;
}
};
이진 검색 트리를 입력하고 이진 검색 트리를 정렬된 이중 연결 목록으로 변환합니다. 아래 그림과 같이
데이터 범위: 입력 이진 트리의 노드 수 0≤n<10000<n<1000, 이진 트리의 각 노드 값 0<val<10000<val<1000
요구 사항: 공간 복잡도 O(1)O( 1) (즉, 원래의 트리 연산에서), 시간 복잡도 O(n)O(n)알아채다:
1. 새 노드를 생성할 수 없으며 트리에서 노드 포인터의 포인팅만 조정할 수 있습니다. 변환이 완료된 후 트리 노드의 왼쪽 포인터는 선행 노드를 가리켜야 하고 트리 노드의 오른쪽 포인터는 후속 노드를 가리켜야 합니다. 2. 포인터를 연결된 노드의 첫 번째 노드로 반환합니다
. 목록
3. 함수에 의해 반환된 TreeNode에는 왼쪽 및 오른쪽 포인터가 있으며 실제로 이중 연결 목록의 데이터 구조로 볼 수 있습니다.4. 이중 연결 목록을 출력할 필요가 없습니다. 프로그램은 반환 값에 따라 자동으로 인쇄합니다.
설명을 입력하세요:
이진 트리의 루트 노드
반환 값 설명:
이중 연결 리스트의 헤드 노드 중 하나입니다.
실시예 1
입력하다:
{10,6,14,4,8,12,16}반환 값:왼쪽에서 오른쪽으로: 4,6,8,10,12,14,16; 오른쪽에서 왼쪽으로: 16,14,12,10,8,6,4;
class Solution {
void Indor(TreeNode* cur,TreeNode*& prev)
{
//确定双向链表
if(cur==nullptr)
return;
Indor(cur->left,prev);
cur->left=prev;
if(prev)
prev->right=cur;
prev=cur;
Indor(cur->right,prev);
}
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
TreeNode* prev=nullptr;
Indor(pRootOfTree,prev);
//判断头结点
TreeNode* head=pRootOfTree;
while(head&&head->left)
{
head=head->left;
}
return head;
}
};
5. 선순서와 중순서로부터 이진 트리 링크를 결정합니다.
두 개의 정수 배열 preorder와 inorder가 주어지면, preorder는 이진 트리의 선순 순회이고 inorder는 동일한 트리의 중위 순회이며, 이진 트리를 구성하고 해당 루트 노드를 반환합니다.
예시 1:
입력: 선주문 = [3,9,20,15,7], 중순 = [9,3,15,20,7]
출력: [3,9,20,null,null,15,7]예시 2:
입력: 선주문 = [-1], 중순 = [-1]
출력: [-1]출처: LeetCode
class Solution {
TreeNode* buildTree(vector<int>& preorder,vector<int>& inorder,int& prie,
int inbegin,int inend)
{
if(inbegin>inend)//结束条件
return nullptr;
TreeNode* root=new TreeNode(preorder[prie]);
int rooti=inbegin;
while(rooti<=inend)
{
if(preorder[prie]==inorder[rooti])
break;
rooti++;
}
++prie;
root->left=buildTree(preorder,inorder,prie,inbegin,rooti-1);
root->right=buildTree(preorder,inorder,prie,rooti+1,inend);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
int i=0;
TreeNode* root=buildTree(preorder,inorder,i,0,inorder.size()-1);
return root;
}
};
6. 이진 트리 강제 버튼을 결정하기 위한 순차 및 후차
class Solution {
TreeNode* _buildTree(vector<int>& inorder,vector<int>& postorder,
int& n,int inbegin,int inend)
{
if(inbegin>inend)
return nullptr;
TreeNode* root=new TreeNode(postorder[n]);
int rooti=inbegin;
while(rooti<=inend)
{
if(postorder[n]==inorder[rooti])
break;
rooti++;
}
n--;
root->right=_buildTree(inorder,postorder,n,rooti+1,inend);//先右再左
root->left=_buildTree(inorder,postorder,n,inbegin,rooti-1);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
int n=postorder.size()-1;
return _buildTree(inorder,postorder,n,0,postorder.size()-1);
}
};
7. 이진 트리 후순 순회 반복 알고리즘
이진 트리의 루트 노드 루트가 주어지면 해당 노드 값의 후위 순회를 반환합니다.
예시 1:
입력: 루트 = [1,null,2,3]
출력: [3,2,1]출처: LeetCode
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root)
{
stack<TreeNode*> st;
vector<int> nums;
TreeNode* cur=root;
TreeNode* prev=nullptr;
while(cur||!st.empty())
{
while(cur)
{
st.push(cur);
cur=cur->left;
}
TreeNode* top=st.top();
if(top->right==nullptr||top->right==prev)//防止重复遍历
{
prev=top;
st.pop();
nums.push_back(top->val);
}
else
{
cur=top->right;
}
}
return nums;
}
};