题目19:1367. 二叉树中的链表
同类题目
前置知识
- 无
题目描述
给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表。
如果在二叉树中,存在一条一直向下的路径,且每个点的数值恰好一一对应以 head 为首的链表中每个节点的值,那么请你返回 True ,否则返回 False 。
一直向下的路径的意思是:从树中某个节点开始,一直连续向下的路径。
示例 1:
输入:head = [4,2,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:true
解释:树中蓝色的节点构成了与链表对应的子路径。
示例 2:
输入:head = [1,4,2,6], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:true
示例 3:
输入:head = [1,4,2,6,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:false
解释:二叉树中不存在一一对应链表的路径。
提示:
- 二叉树和链表中的每个节点的值都满足
1 <= node.val <= 100。 - 链表包含的节点数目在
1到100之间。 - 二叉树包含的节点数目在
1到2500之间。
思路分析
双重深度优先遍历
树中每一个节点都作为 首节点 去匹配链表的 首节点, 只要有一次匹配成功就返回true。
匹配规则
- 链表到头了
head == nullptr,说明已经把链表元素全部匹配了,返回true - 链表还没到末尾,树已经到头了
root == nullptr,返回false - 当前链表元素值与当前树节点元素值不相等
root->val != head->val,返回false
程序代码
方法一:
//https://leetcode.cn/problems/linked-list-in-binary-tree/
//1367. 二叉树中的链表
#include<iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
class Solution {
public:
bool travel(ListNode* head, TreeNode* root)
{
// 说明比对到链表的最后了
if(head == nullptr)
{
return true;
}
// 说明树到低了还没有匹配完链表
if(root == nullptr)
{
return false;
}
bool lv = false;
bool rv = false;
if(root->val == head->val)
{
lv = travel(head->next,root->left);
rv = travel(head->next,root->right);
}
return lv || rv;
}
bool dfs(ListNode* head, TreeNode* root)
{
if(root == nullptr)
{
return false;
}
// 树的所有节点都和链表进行匹配,只要有一个成功即可
return travel(head,root) || dfs(head,root->left) || dfs(head,root->right);
}
bool isSubPath(ListNode* head, TreeNode* root) {
return dfs(head,root);
}
};
复杂度分析
时间复杂度:最坏情况下需要对所有节点进行匹配。假设一共有 n个节点,最坏情况下每次匹配均为到链表的最后一个节点的时候匹配失败,那么一共被匹配到的节点数为2^(len+1)-1 ,即这个节点为根的子树往下len层的满二叉树的节点数,其中len为链表的长度,而二叉树总节点数最多n个,所以枚举节点最多匹配min(2^(len+1),n)次,最坏情况下需要O(n∗min(2^(len+1),n))的时间复杂度。
空间复杂度:O(logN) ,其中logN 为二叉树的高度。
题目感悟
双重dfs 第一次使用,不是很熟练,后续会重点练习一下。
更多相关知识:github.com/pingguo1987…