leetcode 刷題視訊(5) - 二叉樹與圖
二叉樹與圖
問題1 路徑之和2
Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum.
Note: A leaf is a node with no children.
Example:
Given the below binary tree and sum = 22
,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
Return:
[
[5,4,11,2],
[5,8,4,5]
]
連結:https://leetcode-cn.com/problems/path-sum-ii/
思路:
- 從根節點深度遍歷二叉樹,先序遍歷時,將該節點值儲存至path棧中,使用path_value累加節點值。
- 當遍歷至葉節點時,檢查path_value值是否為sum,若為sum,則將path push進result結果中。
- 在後序遍歷時,將該節點值從path棧中彈出,path_value減去節點值。
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
explicit TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
vector<vector<int> > pathSum(TreeNode *root, int sum) {
vector<vector<int> > result;
vector<int> path; // 當前路徑
int path_value = 0;
preoder(root, path_value, sum, path, result);
return result;
}
private:
void preoder(TreeNode *node, int &path_value, int sum, vector<int> &path,
vector<vector<int> > &result) {
if (!node)
return;
path_value += node->val;
path.push_back(node->val);
if (!node->left && !node->right && path_value == sum) {
result.push_back(path);
}
preoder(node->left, path_value, sum, path, result);
preoder(node->right, path_value, sum, path, result);
path_value -= node->val;
path.pop_back();
}
};
問題2 最近公共祖先
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-0Ph6P8Cj-1602252938434)(https://assets.leetcode.com/uploads/2018/12/14/binarytree.png)]
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
Note:
- All of the nodes’ values will be unique.
- p and q are different and both values will exist in the binary tree.
連結:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
-
兩個節點的公共祖先一定在從根節點到這兩個節點的路徑上。
-
由於求公共祖先中最近的公共祖先,那麼即同時出現在這兩條路徑上的離根節點最遠的節點。
-
求p和q節點的路徑,兩路徑上最後一個相同的節點。
問題3 二叉樹轉連結串列
Given a binary tree, flatten it to a linked list in-place.
For example, given the following tree:
1
/ \
2 5
/ \ \
3 4 6
The flattened tree should look like:
1
\
2
\
3
\
4
\
5
\
6
連結:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/
基礎知識 二叉樹的層次遍歷
廣度優先搜尋
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x): val(x), left(NULL), right(NULL) {}
};
void BFS_print(TreeNode* root) {
queue<TreeNode *> Q;
Q.push(root);
while (!Q.empty()) {
TreeNode *node = Q.front();
Q.pop();
print(node);
if (node->left) {
Q.push(node->left);
}
if (node->right) {
Q.push(node->right);
}
}
}
問題4 側面觀察二叉樹
Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
Example:
Input: [1,2,3,null,5,null,4]
Output: [1, 3, 4]
Explanation:
1 <---
/ \
2 3 <---
\ \
5 4 <---
連結:https://leetcode-cn.com/problems/binary-tree-right-side-view/
問題5 課程安排
There are a total of numCourses
courses you have to take, labeled from 0
to numCourses-1
.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
Example 1:
Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0. So it is possible.
Example 2:
Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0, and to take course 0 you should
also have finished course 1. So it is impossible.
Constraints:
- The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
- You may assume that there are no duplicate edges in the input prerequisites.
1 <= numCourses <= 10^5
連結:https://leetcode-cn.com/problems/course-schedule/
思路1 深度優先搜尋
visit[3]=1表示訪問過了,0->2->3再遇到3時並沒有環,不在同一條鏈上。visit[*]=0的節點都在一條鏈上。
struct GraphNode {
int label;
vector<GraphNode *> neighbors;
explicit GraphNode(int x) : label(x) {}
};
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int> > &prerequisites) {
vector<GraphNode *> graph;
vector<int> visit; // 訪問狀態 -1沒有訪問 0正在訪問 1已訪問
for (int i = 0; i < numCourses; i++) {
graph.push_back(new GraphNode(i));
visit.push_back(-1);
}
for (auto & prerequisite : prerequisites) {
GraphNode *begin = graph[prerequisite[1]];
GraphNode *end = graph[prerequisite[0]];
begin->neighbors.push_back(end);
}
// 以各個起點的圖都要判斷一遍
for (int i = 0; i < graph.size(); ++i) {
if (visit[i] == -1 && !DFS_graph(graph[i], visit)) {
return false;
}
}
for (int i = 0; i < numCourses; i++) {
delete graph[i];
}
return true;
}
private:
// 判斷以node為起點的圖裡面有沒有環 true=無環
bool DFS_graph(GraphNode *node, vector<int> &visit) {
visit[node->label] = 0;
for (auto & neighbor : node->neighbors) {
if (visit[neighbor->label] == -1) { //
if (!DFS_graph(neighbor, visit)) {
return false;
}
} else if (visit[neighbor->label] == 0) { // 表示鄰居就是自己
return false;
}
}
visit[node->label] = 1;
return true;
}
};
思路2 廣度優先搜尋
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct GraphNode {
int label;
vector<GraphNode *> neighbors;
explicit GraphNode(int x) : label(x) {}
};
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int> > &prerequisites) {
vector<GraphNode *> graph;
vector<int> degree; // 入度
for (int i = 0; i < numCourses; ++i) {
degree.push_back(0);
graph.push_back(new GraphNode(i));
}
for (auto &prerequisite : prerequisites) {
GraphNode *begin = graph[prerequisite[1]];
GraphNode *end = graph[prerequisite[0]];
begin->neighbors.push_back(end);
degree[end->label]++;
}
queue<GraphNode *> Q;
for (int i = 0; i < numCourses; ++i) {
if (!degree[i]) {
Q.push(graph[i]);
}
}
while (!Q.empty()) {
GraphNode *node = Q.front();
Q.pop();
for (auto &neighbor : node->neighbors) {
degree[neighbor->label]--;
if (!degree[neighbor->label]) {
Q.push(neighbor);
}
}
}
for (auto &i : graph) {
delete i;
}
for (int i : degree) {
if (i) {
return false;
}
}
return true;
}
};
相關文章
- LeetCode 刷題—樹LeetCode
- 【LeetCode刷題(中等程度)】662. 二叉樹最大寬度LeetCode二叉樹
- JavaScript實現-LeetCode刷題-【對稱二叉樹】-第101題!!!JavaScriptLeetCode二叉樹
- 二叉樹與圖二叉樹
- 【刷題】二叉樹非遞迴遍歷二叉樹遞迴
- Leetcode刷題筆記 501. 二叉搜尋樹中的眾數LeetCode筆記
- 5分鐘瞭解二叉樹之LeetCode裡的二叉樹二叉樹LeetCode
- LeetCode刷題記63-109. 有序連結串列轉換二叉搜尋樹【檢視解法】LeetCode
- LeetCode刷題記錄——day5LeetCode
- 資料結構與演算法第二天(二叉樹刷題)資料結構演算法二叉樹
- 【LeetCode-二叉樹】二叉樹前序遍歷LeetCode二叉樹
- 刷題系列 - Python判斷是否映象對稱二叉樹Python二叉樹
- 夜刷:平衡二叉樹的基本操作二叉樹
- leetcode 每日一題 617 合併二叉樹LeetCode每日一題二叉樹
- 【Leetcode千題】617. 合併二叉樹LeetCode二叉樹
- LeetCode題解(Offer26):判斷二叉樹A是否為二叉樹B的子樹(Python)LeetCode二叉樹Python
- Leetcode 二叉樹題目集合 (看完這個面試不會做二叉樹題,辣條給你!!!!!)LeetCode二叉樹面試
- LeetCode-199-二叉樹的右檢視LeetCode二叉樹
- leetcode 199. 二叉樹的右檢視LeetCode二叉樹
- LeetCode199.二叉樹的右檢視LeetCode二叉樹
- 刷題系列 - Python用遞迴實現求二叉樹深度Python遞迴二叉樹
- 刷題系列 - Python實現二叉樹按層級遍歷Python二叉樹
- Leetcode 題解系列 -- 對稱二叉樹(遞迴)LeetCode二叉樹遞迴
- LeetCode 對稱二叉樹LeetCode二叉樹
- LeetCode刷題記錄與題解(C++版本)LeetCodeC++
- LeetCode刷題整理LeetCode
- leetcode刷題(一)LeetCode
- LeetCode刷題 堆LeetCode
- Chapter 3 樹與二叉樹APT二叉樹
- 每天刷個演算法題20160521:二叉樹高度(遞迴與非遞迴)演算法二叉樹遞迴
- 刷題系列 - 序列化和反序列化一個二叉樹二叉樹
- LeetCode題144. 二叉樹的前序遍歷LeetCode二叉樹
- LeetCode第 543 題:二叉樹的直徑(C++)LeetCode二叉樹C++
- 二叉樹與堆二叉樹
- LeetCode 刷題指南(一):為什麼要刷題LeetCode
- 相同二叉樹和鏡面二叉樹問題二叉樹
- LeetCode 刷題筆記LeetCode筆記
- leetcode刷題筆記LeetCode筆記