惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
B
Blog RSS Feed
宝玉的分享
宝玉的分享
腾讯CDC
博客园_首页
T
Tailwind CSS Blog
月光博客
月光博客
博客园 - 司徒正美
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
M
MIT News - Artificial intelligence
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
有赞技术团队
有赞技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
SecWiki News
SecWiki News
美团技术团队
P
Privacy International News Feed
H
Help Net Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
Know Your Adversary
Know Your Adversary
Y
Y Combinator Blog
D
DataBreaches.Net
Project Zero
Project Zero
T
The Blog of Author Tim Ferriss
Cyberwarzone
Cyberwarzone
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
S
Schneier on Security
G
GRAHAM CLULEY
博客园 - 三生石上(FineUI控件)
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
Forbes - Security
Forbes - Security
D
Docker
T
Tenable Blog
S
Secure Thoughts
雷峰网
雷峰网
S
Security @ Cisco Blogs
T
The Exploit Database - CXSecurity.com
The Cloudflare Blog
博客园 - 【当耐特】
Spread Privacy
Spread Privacy
阮一峰的网络日志
阮一峰的网络日志

博客园 - Grandyang

[LeetCode] 1372. Longest ZigZag Path in a Binary Tree 二叉树中的最长交错路径 [LeetCode] 1371. Find the Longest Substring Containing Vowels in Even Counts 每个元音包含偶数次的最长子字符串 [LeetCode] 1370. Increasing Decreasing String 上升下降字符串 [LeetCode] 1368. Minimum Cost to Make at Least One Valid Path in a Grid 使网格图至少有一条有效路径的最小代价 [LeetCode] 1366. Rank Teams by Votes 通过投票对团队排名 [LeetCode] 1365. How Many Numbers Are Smaller Than the Current Number 有多少小于当前数字的数字 [LeetCode] 1363. Largest Multiple of Three 形成三的最大倍数 [LeetCode] 1362. Closest Divisors 最接近的因数 [LeetCode] 1361. Validate Binary Tree Nodes 验证二叉树 [LeetCode] 1360. Number of Days Between Two Dates 日期之间隔几天 [LeetCode] 1359. Count All Valid Pickup and Delivery Options 有效的快递序列数目 [LeetCode] 1358. Number of Substrings Containing All Three Characters 包含所有三种字符的子字符串数目 [LeetCode] 1357. Apply Discount Every n Orders 每隔n个顾客打折 [LeetCode] 1356. Sort Integers by The Number of 1 Bits 根据数字二进制下1 的数目排序 [LeetCode] 1354. Construct Target Array With Multiple Sums 多次求和构造目标数组 [LeetCode] 1353. Maximum Number of Events That Can Be Attended 最多可以参加的会议数目 [LeetCode] 1352. Product of the Last K Numbers 最后 K 个数的乘积 [LeetCode] 1351. Count Negative Numbers in a Sorted Matrix 统计有序矩阵中的负数 [LeetCode] 1349. Maximum Students Taking Exam 参加考试的最大学生数
[LeetCode] 1367. Linked List in Binary Tree 二叉树中的链表
Grandyang · 2024-08-18 · via 博客园 - Grandyang

Given a binary tree root and a linked list with head as the first node.

Return True if all the elements in the linked list starting from the head correspond to some downward path connected in the binary tree otherwise return False.

In this context downward path means a path that starts at some node and goes downwards.

Example 1:

Input: head = [4,2,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: true
Explanation: Nodes in blue form a subpath in the binary Tree.

Example 2:

Input: head = [1,4,2,6], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: true

Example 3:

Input: head = [1,4,2,6,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: false
Explanation: There is no path in the binary tree that contains all the elements of the linked list from head.

Constraints:

  • The number of nodes in the tree will be in the range [1, 2500].
  • The number of nodes in the list will be in the range [1, 100].
  • 1 <= Node.val <= 100 for each node in the linked list and binary tree.

这道题说是给了一棵二叉树,还给了一个链表,问能不能在二叉树中找到一条路径 path,使得其正好是给定的结点链表,题目中例子中的图很好的解释了题意。这里的二叉树的路径并没有限制要从根节点开始,结束位置也不一定要是叶结点,那么理论上不同路径的数量就太多了。如果是想先求出二叉树的所有路径后,再来跟结点链表比较的话,一是太麻烦了,二是效率也不高。最好的办法还是在遍历的过程中就直接开始比较了,比较的方法就是当遇到和此时链表头结点相同的结点时,开始进行下一个结点的比较,由于路径可以去左子结点或者右子结点,所以左右子结点都要去尝试,这里用递归就非常合适了,只要左右子结点任意一个返回 true 了,那么就说明成功匹配了。如果当前的结点和链表头结点的值不相同的话,则分别再去左右子结点进行尝试,此时左右子结点还是跟原来的链表首结点去比较,因为之前没有匹配上,同样,只要左右子结点的递归任意一个返回 true 了,就说明成功匹配上了。根据这种思路写出的代码如下(注意这种下面这种解法是错误的,之后会分析):


// Wrong Solution
class Solution {
public:
    bool isSubPath(ListNode* head, TreeNode* root) {
        if (!head) return true;
        if (!root) return false;
        if (head->val == root->val) {
            return isSubPath(head->next, root->left) || isSubPath(head->next, root->right);
        }
        return isSubPath(head, root->left) || isSubPath(head, root->right);
    }
};

上面的解法虽然简洁,但实际上是错误的解法,这里可以举一个反例:head = [4,2,2], root = [4,2,null,4,null,2],二叉树的结构如下所示:

      4
     /
    2
   /
  4
 /
2

上面解法错误的原因是当 head 匹配完4和2之后,下一个2匹配不上了,因为二叉树中是4,但此时却没有从开头的4重新匹配,而是继续匹配链表中剩下的那个2,这样在跳过二叉树中的第二个4之后,最后一个2就匹配上了,整个就返回了 true。但实际上是错误的,给定的二叉树中并没有一个连续的 4->2->2 路径,相当于找到了类似于字符串中的子序列,而要求的却是子串。正确的做法实际上是对每个结点都当做起始点来匹配一下,这里用一个子函数 dfs 来匹配,匹配的方法就是看链表和二叉树的当前结点值是否相等,是的话再对左右子结点调用递归,只要任意一个返回 true 就行了。在主函数中,调用完 dfs 后,还要分别对左右子结点调用主函数的递归,这样才能保证把每个结点都当起始点来匹配,才能避免上面那个反例的情况,参见代码如下:


class Solution {
public:
    bool isSubPath(ListNode* head, TreeNode* root) {
        if (!head) return true;
        if (!root) return false;
        return dfs(head, root) || isSubPath(head, root->left) || isSubPath(head, root->right);
    }
    bool dfs(ListNode* head, TreeNode* root) {
        if (!head) return true;
        if (!root) return false;
        return head->val == root->val && (dfs(head->next, root->left) || dfs(head->next, root->right));
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1367

参考资料:

https://leetcode.com/problems/linked-list-in-binary-tree

https://leetcode.com/problems/linked-list-in-binary-tree/solutions/524881/python-recursive-solution-o-n-l-time/

https://leetcode.com/problems/linked-list-in-binary-tree/solutions/524821/c-simple-recursion/

LeetCode All in One 题目讲解汇总(持续更新中...)