给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表。如果在二叉树中,存在一条一直向下的路径,且每个点的数值恰好一一对应以 head 为首的链表中每个节点的值,那么请你返回 True ,否则返回 False。
输入:head = [4,2,8],root=[1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
输出:true
解释:树中蓝色的节点构成了与链表对应的子路径。
解法1
class Solution {
public:
bool isSubPath(ListNode* head, TreeNode* root)
{
if(!root)
return false;
else
return isSub(head,root)||isSubPath(head,root->left)||isSubPath(head,root->right);
}
bool isSub(ListNode*head,TreeNode*root)
{
if(!head)
return true;
if(!root)
return false;
if(head->val==root->val)
return isSub(head->next,root->left)||isSub(head->next,root->right);
return false;
}
};
解法2
class Solution {
public:
bool isSubPath(ListNode *head, TreeNode *root) {
//设置一个头结点(所以head是首结点),如果nextvar的值为dumbNode,那么就相当于kmp中nextvar[i] = -1
dumbNode = new ListNode(0);
dumbNode->next = head;
getNextvar(nextvar, dumbNode);
return dfs(dumbNode, root);
}
private:
ListNode *dumbNode;
unordered_map<ListNode *, ListNode *> nextvar;
//带kmp回溯的深度优先搜索
bool dfs(ListNode *head, TreeNode *root) {
if (head->next == nullptr) return true;
if (root == nullptr) return false;
while (head != dumbNode && head->next->val != root->val) head = nextvar[head];
if (root->val == head->next->val) {
if (dfs(head->next, root->left)) return true;
else return dfs(head->next, root->right);
}
if (dfs(head, root->left)) return true;
else return dfs(head, root->right);
}
//初始化nextvar字典
void getNextvar(unordered_map<ListNode *, ListNode *> &nextvar, ListNode *head) {
nextvar[head->next] = head;
auto j = head;
for (auto i = head->next->next; i != nullptr; i = i->next) {
while (j != head && j->next->val != i->val) j = nextvar[j];
if (j->next->val == i->val) {
j = j->next;
}
if (j != head && i->next != nullptr && j->next->val == i->next->val) {
nextvar[i] = nextvar[j];
} else
nextvar[i] = j;
}
}
};