通过二叉树中的链表查找从根开始的路径方向
给定二叉树T的根和链表L ,任务是找到从根开始的路径方向,使得存在从根到树的任何叶节点的路径,使得值是该路径形成链接列表。如果不存在任何这样的路径,则打印“-1” 。
注:左方向的路径用L表示,右方向的路径用R表示。
例子:
Input: LL = 1 -> 2 -> 5 -> 8
1
/ \
2 3
/ \ / \
4 5 6 8
/
8
Output: L R L
Explanation:
The path of linked list in binary tree is as follows:
1
/ \
2 3
/ \ / \
4 5 6 8
/
8
Input: LL = 1 -> 2 -> 4
1
/ \
2 2
/ \ / \
4 5 6 8
/
8
Output: {L, L}
方法:给定的问题可以通过同时遍历二叉树和链表来解决,如果当前节点与链表的当前节点不匹配,则该路径不正确。否则,检查有效路径的其他顺序。请按照以下步骤解决给定的问题:
- 声明一个函数,比如findPath(root, head, path)并在这个函数中执行以下步骤:
- 如果 root 为NULL或 root 的值与 head 的节点值不同,则返回false 。
- 如果当前根节点是叶子节点并且头是最后一个节点,则返回true 。
- 在向量path[]中插入字符'L'并递归调用左子树为findPath(root->left, head->next, path)如果此函数返回的值为true ,则存在路径并从函数返回true 。否则,从向量path[]中弹出最后一个字符。
- 在向量path[]中插入字符'R'并递归调用右子树为findPath(root->right, head->next, path)如果此函数返回的值为true ,则存在路径并从函数返回true 。否则,从向量path[]中弹出最后一个字符。
- 否则,从函数返回false 。
- 如果在给定的二叉树中找到链表,则初始化一个向量,例如存储方向的路径 [] 。
- 调用函数findPath(root, head, path) 。
- 如果向量路径的大小为0 ,则打印“-1” 。否则,打印存储在向量path[]中的路径。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
struct ListNode {
int data;
ListNode* next;
ListNode(int data)
{
this->data = data;
this->next = NULL;
}
};
struct TreeNode {
TreeNode* left;
TreeNode* right;
int val;
TreeNode(int x)
: left(NULL), right(NULL), val(x)
{
}
};
// Function to create the Linked list
ListNode* makeList(int arr[], int n)
{
ListNode* h = NULL;
ListNode* root;
for (int i = 0; i < n; i++) {
int data = arr[i];
ListNode* node = new ListNode(data);
if (h == NULL) {
h = node;
root = h;
}
else {
root->next = node;
root = node;
}
}
return h;
}
// utility function to build tree
// from its level order traversal
TreeNode* build_tree(int nodes[], int n)
{
TreeNode* root = new TreeNode(nodes[0]);
queue q;
bool is_left = true;
TreeNode* cur = NULL;
q.push(root);
for (int i = 1; i < n; i++) {
TreeNode* node = NULL;
if (nodes[i] != '#') {
node = new TreeNode(nodes[i]);
q.push(node);
}
if (is_left) {
cur = q.front();
q.pop();
cur->left = node;
is_left = false;
}
else {
cur->right = node;
is_left = true;
}
}
return root;
}
// Function to find path of linked list
// in binary tree, by traversing the
// tree in pre-order fashion
bool findPath(TreeNode* root, ListNode* head,
vector& path)
{
// Base Case
if (root == NULL) {
return false;
}
// If current tree node is not same
// as the current LL Node, then
// return False
if (root->val != head->data)
return false;
// Complete the path of LL is traced
if (root->left == NULL
and root->right == NULL
and head->next == NULL) {
return true;
}
// First go to left
path.push_back('L');
// If path found in left subtree
if (findPath(root->left,
head->next, path))
return true;
// Pop L because valid path is
// not traced
path.pop_back();
// Go to right
path.push_back('R');
// If path found in right subtree
if (findPath(root->right,
head->next, path))
return true;
// Pop R because valid path
// is not traced
path.pop_back();
return false;
}
// Function to find the valid path
void find(TreeNode* root, ListNode* head)
{
vector path;
// Function call to find the direction
// of the LL path
findPath(root, head, path);
// If there doesn't exists any
// such paths
if (path.size() == 0) {
cout << "-1";
return;
}
// Print the path
for (int i = 0;
i < path.size(); i++) {
cout << path[i] << " ";
}
}
// Driver Code
int main()
{
int tree[] = { 1, 2, 3, 4, 5, 6,
8, -1, -1, 8 };
TreeNode* root = build_tree(tree, 10);
int ll[] = { 1, 2, 5, 8 };
ListNode* head = makeList(ll, 4);
find(root, head);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static class ListNode {
int data;
ListNode next;
ListNode(int data)
{
this.data = data;
this.next = null;
}
};
static class TreeNode {
TreeNode left;
TreeNode right;
int val;
TreeNode(int x){
left = null;
right = null;
val = x;
}
};
// Function to create the Linked list
static ListNode makeList(int arr[], int n)
{
ListNode h = null;
ListNode root = new ListNode(0);
for (int i = 0; i < n; i++) {
int data = arr[i];
ListNode node = new ListNode(data);
if (h == null) {
h = node;
root = h;
}
else {
root.next = node;
root = node;
}
}
return h;
}
// utility function to build tree
// from its level order traversal
static TreeNode build_tree(int nodes[], int n)
{
TreeNode root = new TreeNode(nodes[0]);
Queue q = new LinkedList<>();
boolean is_left = true;
TreeNode cur = null;
q.add(root);
for (int i = 1; i < n; i++) {
TreeNode node = null;
if (nodes[i] != 0) {
node = new TreeNode(nodes[i]);
q.add(node);
}
if (is_left) {
cur = q.peek();
q.remove();
cur.left = node;
is_left = false;
}
else {
cur.right = node;
is_left = true;
}
}
return root;
}
// Function to find path of linked list
// in binary tree, by traversing the
// tree in pre-order fashion
static boolean findPath(TreeNode root, ListNode head,
Vector path)
{
// Base Case
if (root == null) {
return false;
}
// If current tree node is not same
// as the current LL Node, then
// return False
if (root.val != head.data)
return false;
// Complete the path of LL is traced
if (root.left == null
&& root.right == null
&& head.next == null) {
return true;
}
// First go to left
path.add('L');
// If path found in left subtree
if (findPath(root.left,
head.next, path))
return true;
// Pop L because valid path is
// not traced
path.remove(path.size()-1);
// Go to right
path.add('R');
// If path found in right subtree
if (findPath(root.right,
head.next, path))
return true;
// Pop R because valid path
// is not traced
path.remove(path.size()-1);
return false;
}
// Function to find the valid path
static void find(TreeNode root, ListNode head)
{
Vector path = new Vector();
// Function call to find the direction
// of the LL path
findPath(root, head, path);
// If there doesn't exists any
// such paths
if (path.size() == 0) {
System.out.print("-1");
return;
}
// Print the path
for (int i = 0;
i < path.size(); i++) {
System.out.print(path.get(i)+ " ");
}
}
// Driver Code
public static void main(String[] args)
{
int tree[] = { 1, 2, 3, 4, 5, 6,
8, -1, -1, 8 };
TreeNode root = build_tree(tree, 10);
int ll[] = { 1, 2, 5, 8 };
ListNode head = makeList(ll, 4);
find(root, head);
}
}
// This code is contributed by 29AjayKumar
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG{
class ListNode {
public int data;
public ListNode next;
public ListNode(int data)
{
this.data = data;
this.next = null;
}
};
class TreeNode {
public TreeNode left;
public TreeNode right;
public int val;
public TreeNode(int x){
left = null;
right = null;
val = x;
}
};
// Function to create the Linked list
static ListNode makeList(int []arr, int n)
{
ListNode h = null;
ListNode root = new ListNode(0);
for (int i = 0; i < n; i++) {
int data = arr[i];
ListNode node = new ListNode(data);
if (h == null) {
h = node;
root = h;
}
else {
root.next = node;
root = node;
}
}
return h;
}
// utility function to build tree
// from its level order traversal
static TreeNode build_tree(int []nodes, int n)
{
TreeNode root = new TreeNode(nodes[0]);
Queue q = new Queue();
bool is_left = true;
TreeNode cur = null;
q.Enqueue(root);
for (int i = 1; i < n; i++) {
TreeNode node = null;
if (nodes[i] != 0) {
node = new TreeNode(nodes[i]);
q.Enqueue(node);
}
if (is_left) {
cur = q.Peek();
q.Dequeue();
cur.left = node;
is_left = false;
}
else {
cur.right = node;
is_left = true;
}
}
return root;
}
// Function to find path of linked list
// in binary tree, by traversing the
// tree in pre-order fashion
static bool findPath(TreeNode root, ListNode head,
List path)
{
// Base Case
if (root == null) {
return false;
}
// If current tree node is not same
// as the current LL Node, then
// return False
if (root.val != head.data)
return false;
// Complete the path of LL is traced
if (root.left == null
&& root.right == null
&& head.next == null) {
return true;
}
// First go to left
path.Add('L');
// If path found in left subtree
if (findPath(root.left,
head.next, path))
return true;
// Pop L because valid path is
// not traced
path.RemoveAt(path.Count-1);
// Go to right
path.Add('R');
// If path found in right subtree
if (findPath(root.right,
head.next, path))
return true;
// Pop R because valid path
// is not traced
path.RemoveAt(path.Count-1);
return false;
}
// Function to find the valid path
static void find(TreeNode root, ListNode head)
{
List path = new List();
// Function call to find the direction
// of the LL path
findPath(root, head, path);
// If there doesn't exists any
// such paths
if (path.Count == 0) {
Console.Write("-1");
return;
}
// Print the path
for (int i = 0;
i < path.Count; i++) {
Console.Write(path[i]+ " ");
}
}
// Driver Code
public static void Main(String[] args)
{
int []tree = { 1, 2, 3, 4, 5, 6,
8, -1, -1, 8 };
TreeNode root = build_tree(tree, 10);
int []ll = { 1, 2, 5, 8 };
ListNode head = makeList(ll, 4);
find(root, head);
}
}
// This code is contributed by 29AjayKumar
L R L
时间复杂度: O(N + M),其中 N 是二叉树中的节点数,M 是Linked List 的长度。
辅助空间: O(H),其中 H 是二叉树的高度。