日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

二叉树的一些leetcode题目+python(c++)

發布時間:2024/7/23 python 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树的一些leetcode题目+python(c++) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

二叉樹考點主要有:

1.三種遍歷方式,以及構造二叉樹等;

2.求深度,最長直徑,最長路徑,公共祖先等等;

3.合并二叉樹,翻轉二叉樹,判斷平衡性,對稱性等;

4.從前序與中序構造二叉樹,中序與后序構造二叉樹,二叉樹序列化等;

5.二叉搜索樹

1-1.前序遍歷

思路1:遞歸法?

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def helper(self, node):if node is not None:self.res.append(node.val)self.helper(node.left)self.helper(node.right)def preorderTraversal(self, root: TreeNode) -> List[int]:self.res = []self.helper(root)return self.res

c++實現:

/*** Definition for a binary tree node.* 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:vector<int> res;void help(TreeNode* node){if(node !=nullptr){res.push_back(node->val);help(node->left);help(node->right);}}vector<int> preorderTraversal(TreeNode* root) {help(root);return res;} };

思路2棧(迭代法):

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def preorderTraversal(self, root: TreeNode) -> List[int]: res = []if root is None:return resstack = [root]while stack:node = stack.pop()if node:res.append(node.val)stack.append(node.right)stack.append(node.left)return res

c++實現:

/*** Definition for a binary tree node.* 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:vector<int> preorderTraversal(TreeNode* root) {vector<int>res;stack<TreeNode*> stack_A;stack_A.push(root);while(stack_A.size()>0){TreeNode* node = stack_A.top();stack_A.pop();if(node){res.push_back(node->val);stack_A.push(node->right);stack_A.push(node->left);}}return res;} };

1-2.N叉樹的前序遍歷

1.遞歸法?

""" # Definition for a Node. class Node:def __init__(self, val=None, children=None):self.val = valself.children = children """class Solution:def preorder(self, root: 'Node') -> List[int]:res = []def helper(node):if node:res.append(node.val)for child in node.children:helper(child)helper(root)# print('res:', res)return res

c++實現:

/* // Definition for a Node. class Node { public:int val;vector<Node*> children;Node() {}Node(int _val) {val = _val;}Node(int _val, vector<Node*> _children) {val = _val;children = _children;} }; */class Solution { public:vector<int> res;void help(Node* node){if(node!=NULL){res.push_back(node->val);vector<Node* > new_nodes = node->children;for(int i=0;i<new_nodes.size();i++){help(new_nodes[i]);}}}vector<int> preorder(Node* root) {help(root);return res;} };

2.迭代法 利用棧

""" # Definition for a Node. class Node:def __init__(self, val=None, children=None):self.val = valself.children = children """class Solution:def preorder(self, root: 'Node') -> List[int]: res= []if root is None:return resstack = [root]while stack:node = stack.pop()if node:res.append(node.val)stack.extend(node.children[::-1])# print('==res:', res)return res

c++實現:

/* // Definition for a Node. class Node { public:int val;vector<Node*> children;Node() {}Node(int _val) {val = _val;}Node(int _val, vector<Node*> _children) {val = _val;children = _children;} }; */ //后進左子樹先出左子樹 class Solution { public:vector<int> preorder(Node* root) {if(root==NULL){return {};}vector<int> res;stack<Node*> stack_A;stack_A.push(root);while (stack_A.size()>0){Node* node = stack_A.top();stack_A.pop();if(node){res.push_back(node->val);vector<Node*> temp_node_list = node->children;for (int i=temp_node_list.size()-1;i>=0;i--){stack_A.push(temp_node_list[i]);}}}return res;} };

1-3.中序遍歷

思路1:遞歸法?

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def helper(self, node):if node is not None:self.helper(node.left)self.res.append(node.val)self.helper(node.right)def inorderTraversal(self, root: TreeNode) -> List[int]:self.res = []self.helper(root)return self.res

c++實現:

/*** Definition for a binary tree node.* 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:vector<int>res;void help(TreeNode* node){if(node){help(node->left);res.push_back(node->val);help(node->right);}}vector<int> inorderTraversal(TreeNode* root) {help(root);return res;} };

思路2.棧(迭代法)

# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution(object):def inorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""stack = []node = rootoutput = []if root == None: return outputwhile node or stack: # 如果node和aStack都是空的,說明全查完了。while node: # 如果node是空的,說明左邊沒子節點了。stack.append(node)node = node.leftnode = stack.pop() # 左邊沒子節點了就輸出棧頂的節點值,然后從它右邊的子節點繼續。output.append(node.val)node = node.rightreturn output

1-4.后序遍歷

思路1:遞歸?

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def helper(self, node):if node:self.helper(node.left)self.helper(node.right)self.res.append(node.val)def postorderTraversal(self, root: TreeNode) -> List[int]:self.res = []self.helper(root)return self.res

c++實現:

/*** Definition for a binary tree node.* 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:vector<int> res;void help(TreeNode* node){if(node!=nullptr){help(node->left);help(node->right);res.push_back(node->val);}}vector<int> postorderTraversal(TreeNode* root) {help(root);return res;} };

?思路2:棧(迭代法)

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def postorderTraversal(self, root: TreeNode) -> List[int]:stack = []res = []prev = Nonewhile root or stack:while root:stack.append(root)root = root.leftroot = stack.pop()if not root.right or root.right == prev:#右子樹為空或者為根節點值已經遍歷過 prev已經記錄右節點的值res.append(root.val)prev = rootroot = Noneelse:stack.append(root)root = root.rightreturn res

1-5.N叉樹的后序遍歷

1. 解法1 遞歸法

#遞歸法 """ # Definition for a Node. class Node:def __init__(self, val=None, children=None):self.val = valself.children = children """class Solution:def postorder(self, root: 'Node') -> List[int]:if root is None:return Noneres = []def helper(t):if t is None:returnfor child in t.children:helper(child)res.append(t.val)helper(root)return res

c++實現:

/* // Definition for a Node. class Node { public:int val;vector<Node*> children;Node() {}Node(int _val) {val = _val;}Node(int _val, vector<Node*> _children) {val = _val;children = _children;} }; */class Solution { public:vector<int> res;void help(Node* node){if(node == NULL){return ;}for(int i=0; i < node->children.size(); i++){help(node->children[i]);} res.push_back(node->val); }vector<int> postorder(Node* root) {if (root==NULL){return {};}help(root);return res;} };

2. 解法2 迭代法

#迭代法 """ # Definition for a Node. class Node:def __init__(self, val=None, children=None):self.val = valself.children = children """class Solution:def postorder(self, root: 'Node') -> List[int]:if root is None:return Nonestack= [root]res = []while stack:node = stack.pop()res.append(node.val)for child in node.children:stack.append(child)return res[::-1]

1-6.從上到下打印二叉樹

1.BFS:思路利用bfs將每一層節點進行存儲?

# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution(object):def levelOrder(self, root):""":type root: TreeNode:rtype: List[int]"""if root is None:return []quene = [root]res = []while quene:node = quene.pop(0)res.append(node.val)if node.left is not None:quene.append(node.left)if node.right is not None:quene.append(node.right)return res

c++實現:

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:vector<int> levelOrder(TreeNode* root) {vector<int>res;if(!root){return {};}queue<TreeNode*> queue_A;queue_A.push(root);while(!queue_A.empty()){TreeNode* node = queue_A.front();res.push_back(node->val);queue_A.pop();if(node->left){queue_A.push(node->left);}if(node->right){queue_A.push(node->right);}}return res;} };

1-7.從上到下打印二叉樹 II

思路:從跟節點開始一層一層遍歷

1.遞歸法:要注意的是判斷節點是同一層,此時可以傳入一個level參數用于控制層數

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def levelOrder(self, root: TreeNode) -> List[List[int]]:res = []def backtrace(t, level):if t:if len(res)==level:res.append([])res[level].append(t.val)backtrace(t.left,level+1)backtrace(t.right,level+1)backtrace(root,0)return res

2.迭代法 BFS

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def levelOrder(self, root: TreeNode) -> List[List[int]]:res = []if not root:return resquene= [root]while quene: temp = []# print('==len(quene):', len(quene))for i in range(len(quene)):node = quene.pop(0)temp.append(node.val) # print('==temp:', temp) if node.left:quene.append(node.left)if node.right: quene.append(node.right)res.append(temp)return res

c++實現:

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> res; if(!root){return {};}queue<TreeNode* > queue_A;queue_A.push(root);while(!queue_A.empty()){ vector<int> temp_res;int count = queue_A.size();for (int i=0;i<count;i++){ TreeNode* node = queue_A.front();temp_res.push_back(node->val);queue_A.pop();if(node->left){queue_A.push(node->left);}if(node->right){queue_A.push(node->right);}}res.push_back(temp_res); }return res;}};

1-8.從上到下打印二叉樹 III

1.思路BFS :將每一層節點存入隊列進行遍歷,對奇數層進行逆序加入即可

# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution(object):def levelOrder(self, root):""":type root: TreeNode:rtype: List[List[int]]"""if root is None:return []quene = [root]res =[]while quene:temp = []for i in range(len(quene)):node = quene.pop(0)temp.append(node.val)if node.left is not None:quene.append(node.left) if node.right is not None:quene.append(node.right)if len(res)%2==1:res.append(temp[::-1])else:res.append(temp)# print('==res:', res)return res

c++實現:

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector <int>> res;if (root==NULL){return {};}queue<TreeNode* > queue_A;queue_A.push(root);while(!queue_A.empty()){vector <int> temp_res;int count = queue_A.size();for (int i=0;i<count;i++){TreeNode* node = queue_A.front(); temp_res.push_back(node->val);queue_A.pop();if(node->left){queue_A.push(node->left);}if(node->right){queue_A.push(node->right);}}if(res.size()%2==0){res.push_back(temp_res);}else{reverse(temp_res.begin(),temp_res.end());res.push_back(temp_res);} }return res;} };

?1-9.二叉樹的鋸齒形層次遍歷

思路:將每一層的結果進行保存,最后在奇數層反轉即可

1.遞歸解法?

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def help(self,node,level):if node:if len(self.res) == level:self.res.append([])self.res[level].append(node.val)self.help(node.left,level+1)self.help(node.right,level+1)def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:self.res = []if root is None:return self.resself.help(root, 0)for i in range(len(self.res)):if i%2==1:self.res[i] = self.res[i][::-1]return self.res

2.迭代解法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:res = []if root is None:return resquene = [root]while quene:temp = []for i in range(len(quene)):node = quene.pop(0)temp.append(node.val)if node.left is not None:quene.append(node.left)if node.right is not None:quene.append(node.right)res.append(temp)for i in range(len(res)):if i%2==1:res[i] = res[i][::-1] return res

1-10.遞增順序查找樹

思路:中序遍歷獲取每個節點的值,在利用值構建樹?

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def increasingBST(self, root: TreeNode) -> TreeNode:res= []if root is None:return resdef helper(node):if node:helper(node.left)res.append(node.val)helper(node.right)helper(root)print('res:', res)#構建樹new_node = TreeNode(res[0])current_node=new_nodefor i in range(len(res)-1):current_node.left = Nonecurrent_node.right = TreeNode(res[i+1])current_node = current_node.rightreturn new_node

c++實現:

/*** Definition for a binary tree node.* 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:vector <int> res;void help(TreeNode* node){if(node == nullptr){return ;}help(node->left);res.push_back(node->val);help(node->right);}TreeNode* increasingBST(TreeNode* root) {if(root == nullptr){return nullptr;}help(root);TreeNode* new_root = new TreeNode(res[0]);TreeNode* temp_node = new_root;for(int i=1;i<res.size();i++){temp_node->left = nullptr;temp_node->right = new TreeNode(res[i]);temp_node = temp_node->right;}return new_root;} };

?1-11.?二叉樹的右視圖

思路:每一層進行遍歷存儲結果,將每一層的右側結果進行輸出即可。

1.迭代法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def rightSideView(self, root: TreeNode) -> List[int]:res = []if root is None:return resqueue = [root]while queue:size = len(queue)for i in range(len(queue)):node = queue.pop(0)if i == size - 1 :res.append(node.val)if node.left is not None:queue.append(node.left)if node.right is not None:queue.append(node.right)return res

c++實現:

/*** Definition for a binary tree node.* 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:vector<int> res;vector<int> rightSideView(TreeNode* root) {if(root == nullptr) {return {};}queue<TreeNode*> queue_A(r);queue_A.push(root);while(!queue_A.empty()){int count = queue_A.size();for (int i = 0; i < count; i++){TreeNode* temp_node = queue_A.front();if(i == count - 1){res.push_back(temp_node->val);}queue_A.pop();if(temp_node->left!=nullptr){queue_A.push(temp_node->left);}if(temp_node->right!=nullptr){queue_A.push(temp_node->right);} }}return res;} };

2.遞歸法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def rightSideView(self, root: TreeNode) -> List[int]:res =[]if root is None:return resdef helper(node, level):if node is not None:if len(res) == level:res.append([])res[level].append(node.val)helper(node.left,level+1)helper(node.right,level+1)helper(root, 0)# print('====res:', res)fin_res =[]for i in range(len(res)):fin_res.append(res[i][-1])return fin_res

1-12. 找樹左下角的值

思路:bfs

python:

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def findBottomLeftValue(self, root: TreeNode) -> int:nodes = [root]res = []while nodes:temp = nodes[0]for i in range(len(nodes)):node = nodes.pop(0)if node.left:nodes.append(node.left)if node.right:nodes.append(node.right) if len(nodes) == 0:return temp.val

c++:

/*** Definition for a binary tree node.* 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:int findBottomLeftValue(TreeNode* root) {queue<TreeNode* > nodes;nodes.push(root);while(!nodes.empty()){TreeNode* temp = nodes.front();int count = nodes.size();for(int i = 0; i < count; i++){TreeNode* node = nodes.front();nodes.pop();if(node->left){nodes.push(node->left);}if(node->right){nodes.push(node->right);}}if(nodes.size() == 0){return temp->val;}}return -1;} };

2-1.二叉樹的深度

遞歸:python代碼

# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution(object):def maxDepth(self, root):""":type root: TreeNode:rtype: int"""if not root:return 0return max(self.maxDepth(root.left),self.maxDepth(root.right))+1

c++代碼:

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:int maxDepth(TreeNode* root) {if(root==NULL){return 0;}return max(maxDepth(root->left),maxDepth(root->right))+1;} };

2-2:二叉樹的最小深度

思路;求的就是根節點到葉子節點的最小值

python代碼:

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def minDepth(self, root: TreeNode) -> int:if root is None:return 0if root.left and root.right:return min(self.minDepth(root.left),self.minDepth(root.right))+1elif root.left:return self.minDepth(root.left)+1else:return self.minDepth(root.right)+1

?c++代碼:

/*** Definition for a binary tree node.* 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:int minDepth(TreeNode* root) {if (root == nullptr){return 0;}if(root->left && root->right){return min(minDepth(root->left),minDepth(root->right))+1;}else if(root->left){return minDepth(root->left)+1;}else{return minDepth(root->right)+1;}} };

2-3.二叉樹的直徑

思路:遞歸函數用來獲取每一層深度,然后在分別對左右子樹深度求和,這里要注意的是最長直徑不一定過根節點,所有要用一個變量存儲遍歷每個節點時的最大直徑.

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def get_depth(self, node):if node is None:return 0l = self.get_depth(node.left)r = self.get_depth(node.right)self.max_value = max(self.max_value, l+r)return max(l,r)+1def diameterOfBinaryTree(self, root: TreeNode) -> int:self.max_value = 0if root is None:return 0self.get_depth(root)return self.max_value

c++實現:

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:int max_value=0;int help(TreeNode* node){if(!node){return 0;}int l = help(node->left);int r = help(node->right);max_value = max(max_value, l+r);return max(l,r)+1;}int diameterOfBinaryTree(TreeNode* root) {help(root);return max_value;} };

2-4.二叉樹中的最大路徑和

遞歸 主要是要找準遞歸終止條件和遞歸出口,終止條件就是節點為none自然返回值為0, 遞歸出口就是節點本身值+max(左節點增益值,右節點增益值)

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def helper(self, node):if node is None:return 0left_gain = self.helper(node.left)right_gain = self.helper(node.right)self.max_gain = max(self.max_gain,left_gain+right_gain+node.val)return max(node.val+left_gain,node.val+right_gain,0)def maxPathSum(self, root: TreeNode) -> int:self.max_gain = float('-inf')self.helper(root)return self.max_gain

c++實現:

/*** Definition for a binary tree node.* 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:int max_value=INT_MIN;int helper(TreeNode *node){if(!node){return 0;}int left_gain = helper(node->left);int right_gain = helper(node->right);max_value = max(max_value, node->val+left_gain+right_gain);return max(max(node->val+left_gain,0),node->val+right_gain);}int maxPathSum(TreeNode* root) {helper(root);return max_value;} };

2-5.路徑總和

1.遞歸法?

# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution(object):def hasPathSum(self, root, sum):""":type root: TreeNode:type sum: int:rtype: bool"""if not root:return Falseif not root.left and not root.right and root.val==sum:return Truesum -=root.valreturn self.hasPathSum(root.left,sum) or self.hasPathSum(root.right,sum)

c++實現:

/*** Definition for a binary tree node.* 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 hasPathSum(TreeNode* root, int targetSum) {if(root == nullptr){return false;}if (root->left == nullptr && root->right == nullptr && targetSum==root->val){return true;}targetSum -=root->val;return hasPathSum(root->left,targetSum) || hasPathSum(root->right,targetSum);} };

2.利用棧--DFS

class Solution(object):def hasPathSum(self, root, sum):""":type root: TreeNode:type sum: int:rtype: bool"""# # #遞歸終止條件 # if root is None:# return False# if root.left is None and root.right is None and root.val == sum:# return True# sum = sum - root.val# # print('===sum:', sum)# return self.hasPathSum(root.left, sum) or self.hasPathSum(root.right, sum) if not root:return Falsequene = [(root, root.val)]while quene:node,value = quene.pop()if node.left is None and node.right is None and value==sum:return Trueif node.left is not None:quene.append((node.left,value+node.left.val))if node.right is not None:quene.append((node.right,value+node.right.val)) # print('==quene:',quene)return False

3.利用隊列--BFS

class Solution(object):def hasPathSum(self, root, sum):""":type root: TreeNode:type sum: int:rtype: bool"""# # #遞歸終止條件 # if root is None:# return False# if root.left is None and root.right is None and root.val == sum:# return True# sum = sum - root.val# # print('===sum:', sum)# return self.hasPathSum(root.left, sum) or self.hasPathSum(root.right, sum) if not root:return Falsequene = [(root, root.val)]while quene:node,value = quene.pop(0)if node.left is None and node.right is None and value==sum:return Trueif node.left is not None:quene.append((node.left,value+node.left.val))if node.right is not None:quene.append((node.right,value+node.right.val)) # print('==quene:',quene)return False

2-6:路徑總和 II

思路:回溯 這種里面要調用兩層回溯的  track就不要放在遞歸函數里面了

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def dfs(self, node, sum_):if node is None:return 0store = self.track.copy()self.track.append(node.val)# print('==self.track:', self.track)if node.left is None and node.right is None and sum_==node.val: self.res.append(self.track)sum_ -= node.valself.dfs(node.left, sum_)self.dfs(node.right, sum_)# self.track.pop()self.track = storedef pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:self.res = []self.track = []self.dfs(root, sum)return self.res

c++實現:

/*** Definition for a binary tree node.* 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:vector<vector<int>> res;vector<int> track;void dfs(TreeNode* root, int targetSum){if(root==nullptr){return ;}vector<int> store;store = track;track.push_back(root->val); if(root->left==nullptr && root->right==nullptr && targetSum==root->val){res.push_back(track);}targetSum -= root->val;dfs(root->left, targetSum);dfs(root->right, targetSum);track = store;}vector<vector<int>> pathSum(TreeNode* root, int targetSum) {dfs(root, targetSum);return res;} };

2-7:路徑總和 III

思路:用一個列表存儲從節點開始的數字和

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right #用列表記錄從每一個節點開始的和 class Solution:def dfs(self, node, sum_list, sum):if node is None:return 0 sum_list = [num+node.val for num in sum_list]sum_list.append(node.val)for num in sum_list:if num==sum:self.res+=1self.dfs(node.left, sum_list, sum)self.dfs(node.right, sum_list, sum)def pathSum(self, root: TreeNode, sum: int) -> int:self.res = 0self.dfs(root, [], sum)return self.res

c++實現:

/*** Definition for a binary tree node.* 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:int res;void dfs(TreeNode* node, vector<int> num_list, int sum){if(node == nullptr){return ;}for (int i=0; i<num_list.size(); i++){num_list[i] += node->val;} num_list.push_back(node->val);for(int i=0; i<num_list.size(); i++){if(num_list[i]==sum){res++;}}dfs(node->left, num_list, sum);dfs(node->right, num_list, sum);}int pathSum(TreeNode* root, int sum) {vector<int> num_list;dfs(root, num_list, sum);return res;} };

2-8.二叉樹的所有路徑

給定一個二叉樹,返回所有從根節點到葉子節點的路徑

思路:dfs

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def dfs(self, node,path):if not node:returnpath +=str(node.val)if node.left is None and node.right is None:self.res.append(path)else:path+="->"self.dfs(node.left, path)self.dfs(node.right, path)def binaryTreePaths(self, root: TreeNode) -> List[str]:self.res = []self.dfs(root, "")return self.res

c++實現:

/*** Definition for a binary tree node.* 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:vector<string> res;void dfs(TreeNode* node, string path){if(node == nullptr){return ;}path+=to_string(node->val);if(node->left == nullptr && node->right == nullptr){res.push_back(path);}else{path+="->";dfs(node->left, path);dfs(node->right, path);}}vector<string> binaryTreePaths(TreeNode* root) {dfs(root, "");return res;} };

2-9.求根節點到葉節點數字之和

python:

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def help(self, node, path):if node is None:returnpath += str(node.val)if node.left is None and node.right is None:self.res.append(path)else: self.help(node.left, path)self.help(node.right, path)def sumNumbers(self, root: TreeNode) -> int:self.res = []self.help(root, '')return sum(map(int, self.res))

c++代碼:

/*** Definition for a binary tree node.* 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:vector<string> res;void help(TreeNode* node, string path){if(node == nullptr){return ;}path += to_string(node->val);if(node->left == nullptr && node->right == nullptr){res.push_back(path);}else{help(node->left, path);help(node->right, path);}}int sumNumbers(TreeNode* root) {help(root, "");int int_res;for(auto str_:res){int_res += atoi(str_.c_str());}return int_res;} };

3-1.合并二叉樹

思路:采用前序遍歷訪問二叉樹,如果節點其一為none,就返回另一個

1.遞歸法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode:if t1 is None:return t2if t2 is None:return t1t1.val+=t2.valt1.left = self.mergeTrees(t1.left,t2.left)t1.right = self.mergeTrees(t1.right,t2.right)return t1

2.迭代法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode:if t1 is None:return t2stack= [(t1,t2)]while stack:t = stack.pop()if t[0] is None or t[1] is None:continuet[0].val +=t[1].valif t[0].left is None:t[0].left = t[1].leftelse:stack.append((t[0].left, t[1].left))if t[0].right is None:t[0].right = t[1].rightelse:stack.append((t[0].right, t[1].right))return t1

c++實現:

/*** Definition for a binary tree node.* 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:TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {if(root1 == nullptr){return root2;}if(root2 == nullptr){return root1;}root1->val += root2->val;root1->left = mergeTrees(root1->left, root2->left);root1->right = mergeTrees(root1->right, root2->right);return root1;} };

3-2:翻轉二叉樹

思路:遞歸遍歷左右子樹進行交換即可

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def invertTree(self, root: TreeNode) -> TreeNode:if root is None:return Noneleft = self.invertTree(root.left)right = self.invertTree(root.right)root.left = rightroot.right = leftreturn root

c++實現:

/*** Definition for a binary tree node.* 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:TreeNode* invertTree(TreeNode* root) {if(root == nullptr){return nullptr;}TreeNode* left = invertTree(root->left);TreeNode* right = invertTree(root->right);root->left = right;root->right = left;return root;} };

3-3.檢查二叉樹平衡性

思路:遞歸求解節點左右分支的最長路徑,如果路徑之差絕對值大于1,就認為是非平衡。?

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def depth(self, node):if node is None:return 0return max(self.depth(node.left), self.depth(node.right)) + 1def isBalanced(self, root: TreeNode) -> bool:if root is None:return Trueif abs(self.depth(root.left) - self.depth(root.right)) > 1:return Falsereturn self.isBalanced(root.left) and self.isBalanced(root.right)

c++實現:

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:int get_height(TreeNode* node){if(node == NULL){return 0;}return max(get_height(node->left), get_height(node->right))+1;}bool isBalanced(TreeNode* root) {if(root == NULL){return true;}int left_value = get_height(root->left);int right_value = get_height(root->right);// cout<<left_value<<endl;// cout<<right_value<<endl;if(abs(left_value-right_value)>1){return false;}return isBalanced(root->left) && isBalanced(root->right);} };

3-4.對稱二叉樹

1.解法1 bfs 對每個節點的左子樹和右子樹進行判斷相等

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def isSymmetric(self, root: TreeNode) -> bool:def check(t1,t2):if t1==None and t2==None:return Trueif t1==None or t2==None:return Falseif (t1.val != t2.val):return Falsereturn check(t1.left,t2.right) and check(t1.right,t2.left)return check(root,root)

c++實現:

/*** Definition for a binary tree node.* 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 dfs(TreeNode* t1, TreeNode* t2){if(t1==nullptr && t2==nullptr){return true;}if(t1==nullptr || t2==nullptr){return false;}return dfs(t1->left,t2->right) && dfs(t1->right,t2->left);}bool isSymmetric(TreeNode* root) {return dfs(root, root);} };

2.解法2 dfs ,首先對根節點左子樹進行前序遍歷并存儲值,對根節點右子樹的右分支進行遍歷在對左分支進行遍歷并存儲值,最后比較兩個列表的值。

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def isSymmetric(self, root: TreeNode) -> bool:if root==None:return Truedef leftsearch(t1, left):if t1==None:left.append(None)else:left.append(t1.val)leftsearch(t1.left,left)leftsearch(t1.right,left)def rightsearch(t2, right):if t2==None:right.append(None)else:right.append(t2.val)rightsearch(t2.right,right)rightsearch(t2.left,right)left = []right = []leftsearch(root.left, left)rightsearch(root.right, right)if left==right:return Trueelse:return False

3-5.相同的樹

思路:判斷節點 相等 判斷節點的值相等 在遞歸左右子樹

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:if not p and not q:#兩個節點都為空return Trueif (not p and q) or (not q and p):#兩個節點只要有一個不為空return Falseif p.val != q.val:return Falsereturn self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)

c++實現:

/*** Definition for a binary tree node.* 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 isSameTree(TreeNode* p, TreeNode* q) {if(p==nullptr && q==nullptr){return true;}if(p==nullptr || q==nullptr){return false;}if(p->val != q->val){return false;}return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);} };

3-6.左葉子之和

思路:判斷左葉子的條件:節點的左指針不為none,同時節點的左指針的左指針和節點的左指針的右指針為none

1.遞歸寫法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def sumOfLeftLeaves(self, root: TreeNode) -> int:self.result = 0 def get_res(t):if t is None:return 0 if t is not None and t.left is not None and t.left.left is None and t.left.right is None:self.result = self.result + t.left.val get_res(t.left)get_res(t.right)get_res(root)return self.result

c++實現:

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:int res;void help(TreeNode* node){if(node == NULL){return ;}if(node->left !=NULL && node->left->left ==NULL && node->left->right ==NULL){res+=node->left->val;}help(node->left);help(node->right);}int sumOfLeftLeaves(TreeNode* root) {if(root == NULL){return 0;}help(root);return res;} };

2.迭代寫法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def sumOfLeftLeaves(self, root: TreeNode) -> int:if root is None:return 0 stack = [root]res = 0while stack:node = stack.pop()if node is not None:if node.left is not None and node.left.left is None and node.left.right is None:res += node.left.valstack.append(node.left)stack.append(node.right)return res

4-1.從前序與中序遍歷序列構造二叉樹

思路:

終止條件:前序或中序數組為空.
根據前序數組第一個元素,拼出根節點,再將前序數組和中序數組分成兩半,遞歸的處理前序數組左邊和中序數組左邊,遞歸的處理前序數組右邊和中序數組右邊。

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: # 遞歸終止條件 前序遍歷節點數或中序遍歷節點數為0if len(preorder)==0 or len(inorder)==0:return Noneroot = TreeNode(preorder[0])#根據前序遍歷特點創建根節點#再根據中序遍歷特點用根節點找出左右子樹的分界點mid_index = inorder.index(preorder[0])#再利用中序遍歷和前序遍歷的左子樹節點個數相等特點 構造根節點左子樹root.left = self.buildTree(preorder[1:mid_index+1],inorder[:mid_index])#再利用中序遍歷和前序遍歷的右子樹節點個數相等特點 構造根節點右子樹root.right = self.buildTree(preorder[mid_index+1:],inorder[mid_index+1:])return root

c++實現:

/*** Definition for a binary tree node.* 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:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {if(preorder.empty() || preorder.empty()) {return nullptr;}TreeNode* root = new TreeNode(preorder[0]);int root_value = preorder[0];int middle = 0;for (int i=0;i<inorder.size();i++){if(inorder[i]==root_value){middle = i;break;}}vector<int> leftInorder(inorder.begin(), inorder.begin() + middle);vector<int> rightInorder(inorder.begin() + middle + 1, inorder.end());vector<int> leftPreorder(preorder.begin()+1, preorder.begin() + middle+1);vector<int> rightPreorder(preorder.begin() + middle + 1, preorder.end());root->left = buildTree(leftPreorder,leftInorder);root->right = buildTree(rightPreorder,rightInorder);return root;} };

4-2.從中序與后序遍歷序列構造二叉樹

/*** Definition for a binary tree node.* 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:TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {if(inorder.empty() || postorder.empty()){return nullptr;}TreeNode* root = new TreeNode(postorder[postorder.size()-1]);int root_value = postorder[postorder.size()-1];int middle = 0;for (int i=0; i<inorder.size(); i++){if(inorder[i] == root_value){middle = i;break;}}// cout<<"===middle:"<<middle<<endl;vector<int> left_inorder(inorder.begin(), inorder.begin() + middle);vector<int> right_inorder(inorder.begin() + middle + 1, inorder.end());vector<int> left_postorder(postorder.begin(), postorder.begin() + middle);vector<int> right_postorder(postorder.begin() + middle, postorder.end() - 1);root->left = buildTree(left_inorder, left_postorder);root->right = buildTree(right_inorder, right_postorder);return root;} };

?思路:和上一題類似

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:#遞歸終止條件if len(inorder)==0 or len(postorder)==0:return None#創建根節點root = TreeNode(postorder[-1])#根據中序遍歷獲取分離點mid_index = inorder.index(postorder[-1])# print('==mid_index:',mid_index)#獲取左子樹root.left = self.buildTree(inorder[:mid_index],postorder[:mid_index])#獲取右子樹root.right = self.buildTree(inorder[mid_index+1:],postorder[mid_index:-1])return root

c++實現:

/*** Definition for a binary tree node.* 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:TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {if(inorder.empty() || postorder.empty()){return nullptr;}TreeNode* root = new TreeNode(postorder[postorder.size()-1]);int root_value = postorder[postorder.size()-1];int middle = 0;for (int i=0; i<inorder.size(); i++){if(inorder[i] == root_value){middle = i;break;}}// cout<<"===middle:"<<middle<<endl;vector<int> left_inorder(inorder.begin(), inorder.begin() + middle);vector<int> right_inorder(inorder.begin() + middle + 1, inorder.end());vector<int> left_postorder(postorder.begin(), postorder.begin() + middle);vector<int> right_postorder(postorder.begin() + middle, postorder.end() - 1);root->left = buildTree(left_inorder, left_postorder);root->right = buildTree(right_inorder, right_postorder);return root;} };

由上面兩題可知對于前序遍歷:跟左右,中序遍歷:左跟右,后序遍歷左右跟;

采前序遍歷和中序遍歷,中序遍歷和后序遍歷都能通過根節點分離出左右,而前序遍歷和后序遍歷就不能,故而后者無法恢復出二叉樹.

4-3.二叉樹的序列化與反序列化

# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Codec:def serialize(self, root):"""Encodes a tree to a single string.:type root: TreeNode:rtype: str"""# return self.pre_order(root)# self.in_order(root)from collections import dequeres = []queue= [root]#deque([root])while queue:root = queue.pop(0)#left()if root:res.append(root.val)queue.extend([root.left, root.right])else:res.append('#')return str(res)def deserialize(self, data):"""Decodes your encoded data to tree.:type data: str:rtype: TreeNode"""# print(self.pre_rest, self.in_res)print(data)nodes = [(TreeNode(v) if v != '#' else None) for v in eval(data)]i, j, n = 0, 1, len(nodes)while j < n:if nodes[i]:nodes[i].left = nodes[j]j += 1nodes[i].right = nodes[j]j += 1i += 1return nodes[0] # Your Codec object will be instantiated and called as such: # ser = Codec() # deser = Codec() # ans = deser.deserialize(ser.serialize(root))

5-1.二叉搜索樹的最近公共祖先

思路:

1.從根節點開始遍歷樹
2.如果節點 p 和節點 q 都在右子樹上,那么以右孩子為根節點繼續 1 的操作
3.如果節點 p 和節點 q 都在左子樹上,那么以左孩子為根節點繼續 1 的操作
4.如果條件 2 和條件 3 都不成立,這就意味著我們已經找到p 和q 的公共祖先了

解法1:當成普通二叉樹

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if root==p or root==q or root is None:return rootleft_node = self.lowestCommonAncestor(root.left,p,q)right_node = self.lowestCommonAncestor(root.right,p,q)if left_node is None:return right_nodeif right_node is None:return left_nodereturn root

解法2利用二叉搜索樹特點根節點值和左右子樹值大小的特點.遞歸法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None #利用二叉搜索樹的特點 class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':print('==root.val:', root.val)if root.val< min(p.val, q.val):#都大于根節點的值 將右孩子作為根節點return self.lowestCommonAncestor(root.right, p, q)elif root.val > max(p.val, q.val):#都小于根節點的值 將左孩子作為根節點return self.lowestCommonAncestor(root.left, p, q)else:#找到公共祖先return root

c++實現:

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root->val<min(p->val,q->val)){return lowestCommonAncestor(root->right,p,q);}if(root->val>max(p->val,q->val)){return lowestCommonAncestor(root->left,p,q);}return root;} };

解法3.迭代法

#利用二叉搜索樹的特點 class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':node = rootwhile node:if node.val < min(p.val,q.val):node = node.rightelif node.val > max(p.val,q.val):node = node.leftelse:return node

5-2:二叉樹的最近公共祖先

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if root is None or root==p or root==q:#遞歸終止條件 節點為空 或者節點等于p,q其中之一return rootleft = self.lowestCommonAncestor(root.left, p, q)#遍歷左子樹right = self.lowestCommonAncestor(root.right, p, q)#遍歷右子樹if left is None:#左子樹為空 就去右子樹 return rightif right is None:#右子樹為空 就去左子樹 return leftreturn root#左右子樹都不為空 說明找到了節點 

c++實現:

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == NULL){return NULL;}if(root->val == p->val || root->val == q->val){return root;}TreeNode* left_node = lowestCommonAncestor(root->left,p,q);TreeNode* right_node = lowestCommonAncestor(root->right,p,q);if(left_node !=NULL && right_node!=NULL){return root;}if (left_node==NULL){return right_node;}return left_node;} };

5-3.二叉搜索樹中的搜索

思路:利用二叉樹特點

1.從根節點遍歷二叉樹

2.如果給定值小于跟節點值,根節點替換為右孩子節點,否則根節點替換為左孩子節點

1.遞歸法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None #遞歸法 class Solution:def searchBST(self, root: TreeNode, val: int) -> TreeNode:if not root or root.val ==val:#截止條件return rootif root.val < val:return self.searchBST(root.right,val)else:return self.searchBST(root.left,val)

c++實現:

/*** Definition for a binary tree node.* 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:TreeNode* searchBST(TreeNode* root, int val) {if(root == nullptr){return root;}if(root->val == val){return root;}if(root->val > val){return searchBST(root->left,val);}else{return searchBST(root->right,val);}} };

2.迭代法

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None #迭代法 class Solution:def searchBST(self, root: TreeNode, val: int) -> TreeNode:while root is not None and root.val !=val:root = root.left if root.val >val else root.rightreturn root

5-4.把二叉搜索樹轉換為累加樹?

思路:其實就是逆中序遍歷,利用二叉搜索樹的特點,跟節點值更新為右孩子和根節點值之和,左孩子值更新為根節點與左孩子值之和。

1.迭代法:

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def convertBST(self, root: TreeNode) -> TreeNode:stack = []node = rootvalue = 0while stack or node:while node:#把跟節點與右子樹節點依次壓進棧 實現逆中序遍歷stack.append(node)node = node.rightprint('==stack:', stack)node = stack.pop()print('==node:',node)value += node.valnode.val = valueprint('==node.left:', node.left)node = node.leftreturn root

2.遞歸法:

其中res存儲逆中序遍歷(右根左)的值,便于查看

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:def helper(self, node):if node:self.helper(node.right)# self.res.append(node.val)self.value+=node.valnode.val = self.valueself.helper(node.left)def convertBST(self, root: TreeNode) -> TreeNode:# self.res =[]self.value = 0self.helper(root)return root

c++實現:

/*** Definition for a binary tree node.* 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:int res = 0;void help(TreeNode* node){if(node == nullptr){return ;}help(node->right);res += node->val;node->val = res;help(node->left);}TreeNode* convertBST(TreeNode* root) {help(root);return root;} };

5-5.刪除二叉搜索樹中的節點

#思路:中序遍歷,如果值大于節點值,則去右子樹,否則去左子樹
#如果 找的的節點是葉子節點,則進行刪除置None即可
#如果找到的節點不是葉子節點,有右子樹,則用后繼節點(比當前節點值大的最小值)代替找到的節點,在將后繼節點置None
#如果找到的節點不是葉子節點,有左子樹,則用前驅節點(比當前節點值小的最大值)代替找到的節點,在將前驅節點置None?

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution:#獲取節點的后繼節點(比當前節點大的最小值)def get_successor(self, node):node = node.rightwhile node.left:node = node.leftreturn node.val#獲取節點的前驅節點(比當前節點小的最大值)def get_pressor(self, node):node = node.leftwhile node.right:node = node.rightreturn node.valdef deleteNode(self, root: TreeNode, key: int) -> TreeNode:if root is None:return Noneif root.val<key:root.right = self.deleteNode(root.right, key)elif root.val>key:root.left = self.deleteNode(root.left, key)else:if root.left is None and root.right is None:#葉子節點root = None elif root.right:#要刪除的節點有右子樹 利用后繼節點root.val = self.get_successor(root)root.right = self.deleteNode(root.right,root.val)#刪除后繼節點else:#要刪除的節點有左子樹 利用前驅節點root.val = self.get_pressor(root)root.left = self.deleteNode(root.left,root.val)#刪除前驅節點 return root

c++實現:?

/*** Definition for a binary tree node.* 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:int get_succesor(TreeNode* node){//得到后繼節點node = node->right;while(node->left != nullptr){node = node->left;}return node->val;}int get_pressor(TreeNode* node){node = node->left;while(node->right != nullptr){node = node->right;}return node->val;}TreeNode* deleteNode(TreeNode* root, int key) {if(root == nullptr){return nullptr;}if(root->val < key){root->right= deleteNode(root->right, key);}else if(root->val >key){root->left= deleteNode(root->left, key);}else{if(root->left == nullptr && root->right == nullptr){root = nullptr;}else if(root->right != nullptr){root->val = get_succesor(root);root->right = deleteNode(root->right, root->val);}else{root->val = get_pressor(root);root->left = deleteNode(root->left, root->val);}}return root;} };

5-6.不同的二叉搜索樹

思路:卡塔蘭數

將 1?(i?1) 序列作為左子樹,將 (i+1)?n 序列作為右子樹。接著我們可以按照同樣的方式遞歸構建左子樹和右子樹。

在上述構建的過程中,由于根的值不同,因此我們能保證每棵二叉搜索樹是唯一的.也就得到卡塔蘭數

class Solution(object):def numTrees(self, n):""":type n: int:rtype: int"""#狀態方程 和G(j-1) * G(n-j)dp = [0]*(n+1)#0 1樹都為1dp[0], dp[1] = 1, 1for i in range(2,n+1):for j in range(1,i+1):dp[i] += dp[j-1]*dp[i-j]# print('==dp:', dp)return dp[-1]

c++實現:

class Solution { public:int numTrees(int n) {vector<int> res(n+1,0); res[0] = 1;res[1] = 1;for (int i=2;i<n+1;i++){for (int j=1;j<i+1;j++){res[i] += res[j-1] * res[i-j];}}return res[n];} };

5-7.不同的二叉搜索樹 II

思路:

# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution(object):def generateTrees(self, n):""":type n: int:rtype: List[TreeNode]"""if n==0:return []def build_tree(left,right):if left > right:#遞歸終止條件 如果左邊計數大于右邊 說明要返回空值return [None]all_trees = []for i in range(left, right+1):left_trees = build_tree(left, i-1)right_trees = build_tree(i+1, right)for l in left_trees:#遍歷可能的左子樹for r in right_trees:#遍歷可能的右子樹cur_tree = TreeNode(i)#根節點cur_tree.left= lcur_tree.right = rall_trees.append(cur_tree)return all_treesres = build_tree(1,n)return res

5.8.驗證二叉搜索樹

思路1:遞歸處理右子樹節點和 左子樹節點的值和上下界限的大小

# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = Noneclass Solution(object):def isValidBST(self, root):""":type root: TreeNode:rtype: bool"""def helper(node, lower=float('-inf'), upper=float('inf')):if node is None:#遞歸終止條件 節點為Nonereturn Trueval = node.val#獲取節點值#如果節點值大于上界或者小于下界 ,返回falseif val >= upper or val <= lower :return False#遞歸右子樹 對于右子樹 具備下界if not helper(node.right, val, upper):return False#遞歸左子樹 對于左子樹 具備上界if not helper(node.left, lower, val):return Falsereturn Truereturn helper(root)

c++實現:

/*** Definition for a binary tree node.* 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 help(TreeNode* node, long long lower,long long upper){if(node == nullptr){return true;}if(node->val <= lower || node->val >= upper){return false;}if(!help(node->right, node->val, upper)){return false;}if(!help(node->left, lower, node->val)){return false;}return true;}bool isValidBST(TreeNode* root) {if(root == nullptr){return true;}return help(root, LONG_MIN, LONG_MAX);} };

思路2 :利用中序遍歷的特點,遍歷左子樹和根節點,如果值不滿足二叉搜索數特點就返回false.

# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution(object):def isValidBST(self, root):stack = []node = rootinorder_value = float('-inf')while stack or node:#出棧終止條件while node:#進棧stack.append(node)node = node.leftnode = stack.pop()#左節點# 如果中序遍歷得到的節點的值小于等于前一個 inorder_value,說明不是二叉搜索樹if node.val <=inorder_value:return Falseinorder_value = node.val node=node.rightreturn True

思路3:遞歸實現中序遍歷 左 跟 右 也就是遍歷的后一個節點值要大于上一個 否則不滿足二叉搜索樹特點

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right #中序遍歷 左跟右 class Solution:def __init__(self):self.pre = float('-inf')def isValidBST(self, root: TreeNode) -> bool:if root is None:return Trueif not self.isValidBST(root.left):#先訪問左子樹return Falseif root.val<=self.pre:#在訪問當前節點return False;print('==before self.pre:',self.pre)self.pre = root.valprint('==after self.pre:',self.pre)return self.isValidBST(root.right)#在訪問右子樹

5.9將有序數組轉換為二叉搜索樹

思路:二分法

python代碼?

# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def help(self, left, right):if left > right:return Nonemid = left + (right - left) // 2root = TreeNode(self.nums[mid])root.left = self.help(left, mid - 1)root.right = self.help(mid + 1, right)return rootdef sortedArrayToBST(self, nums: List[int]) -> TreeNode: self.nums = numsreturn self.help(0, len(nums) - 1) # Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution:def help(self, left, right):if left > right:return Nonemid = left + (right - left) // 2root = TreeNode(self.nums[mid])root.left = self.help(left, mid - 1)root.right = self.help(mid + 1, right)return rootdef sortedArrayToBST(self, nums: List[int]) -> TreeNode: self.nums = numsreturn self.help(0, len(nums) - 1)

總結

以上是生活随笔為你收集整理的二叉树的一些leetcode题目+python(c++)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

国产成人av电影在线 | 福利一区视频 | 国产呻吟在线 | 国产男女无遮挡猛进猛出在线观看 | 九九热在线免费观看 | 亚洲mv大片欧洲mv大片免费 | 亚洲成人一二三 | 免费视频一区二区 | 在线免费中文字幕 | 99久热在线精品视频 | 久久综合加勒比 | 亚洲国内精品在线 | 国产黄色一级片在线 | 最近中文字幕在线播放 | 99国产在线观看 | 亚洲精品乱码久久久久久写真 | 国产精品美女久久久久久 | 九九爱免费视频在线观看 | 插综合网| 九九涩涩av台湾日本热热 | 国产精品久久久久999 | 天天插天天色 | 久久精视频 | 欧美韩日在线 | 国产精品99久久久久的智能播放 | 亚洲国产精品第一区二区 | 国产小视频免费观看 | 特级黄色片免费看 | 日韩在线视频免费播放 | 国产一区二区日本 | 免费在线播放视频 | 久久午夜色播影院免费高清 | 黄色三级在线看 | 欧美一级黄色片 | 日日色综合 | 日韩av在线小说 | 激情av网址 | 亚洲免费专区 | 少妇精品久久久一区二区免费 | 欧美aaa一级 | www四虎影院 | 日本三级国产 | 亚洲精品久久久久999中文字幕 | 91成人精品国产刺激国语对白 | 五月天色综合 | 亚洲天堂首页 | 国产亚洲精品久久久久久无几年桃 | 成人在线免费av | 欧美精品在线视频观看 | 久久夜av | 午夜久久久影院 | 国产手机在线观看视频 | 99精品久久99久久久久 | a极黄色片 | 国产做aⅴ在线视频播放 | 在线免费国产视频 | 国产97在线视频 | 国产精品福利视频 | 国产成人av电影在线观看 | 久久视 | 久久精品亚洲 | 激情五月伊人 | 免费观看特级毛片 | 日韩欧美国产精品 | 亚洲精品一区二区久 | 国产精品久久一卡二卡 | 久久久午夜精品理论片中文字幕 | 亚洲午夜精品久久久 | 日本动漫做毛片一区二区 | 国产婷婷精品av在线 | 99久久婷婷国产综合精品 | 国产美腿白丝袜足在线av | 日韩欧美在线免费观看 | 粉嫩av一区二区三区四区五区 | 午夜久久福利 | 国产精品资源在线 | 中文字幕传媒 | 五月婷婷欧美视频 | 在线免费观看黄色 | 日韩美视频| 最新av免费在线观看 | 免费激情网 | 精品伊人久久久 | 丁香在线观看完整电影视频 | 成人av影视观看 | 天天色天天干天天色 | 色偷偷88888欧美精品久久 | 狠狠干婷婷 | 一级黄色免费网站 | 久草视频手机在线 | 国产成人精品一区二区在线 | 亚洲 欧美变态 另类 综合 | 亚洲激情六月 | 日韩视频1区 | 国产精品门事件 | 99久久综合精品五月天 | 超碰在线人人97 | 日韩中文字幕a | 午夜av免费观看 | 久久久久区 | 欧美精品久久久久性色 | 伊人影院99 | 欧美一区二视频在线免费观看 | 国产成人精品网站 | 亚洲 欧洲 国产 日本 综合 | a v在线观看| 91亚洲精品乱码久久久久久蜜桃 | 99爱视频在线观看 | 免费污片 | 日本黄色免费看 | 成年人视频免费在线播放 | 五月婷婷,六月丁香 | 亚洲日本va中文字幕 | 国产精品免费在线播放 | 久久国产精品99国产精 | 国产剧情一区二区 | 欧美日韩精品在线观看视频 | 中文字幕免费观看全部电影 | 国产在线一区二区三区播放 | 久久久久 | 在线之家官网 | 国产黄色在线看 | 色国产精品一区在线观看 | 成人国产综合 | 久久免费av | 日韩欧美一区二区三区在线 | 久艹视频免费观看 | 一区二区三区在线观看 | 亚洲成人中文在线 | www黄色| 婷婷丁香在线视频 | 国产精品久久久久毛片大屁完整版 | 国内精自线一二区永久 | 久久黄色免费 | 欧美成年黄网站色视频 | 婷婷5月激情5月 | 五月婷婷另类国产 | 精品久久久久久久久久国产 | 久久久久电影网站 | 国产精品99久久久精品免费观看 | 看片的网址 | 黄色软件网站在线观看 | 国产美女免费 | 午夜丁香网 | 天天操夜夜操夜夜操 | 国产精品一区二区三区四 | 国内精品久久久久久中文字幕 | 国产免费大片 | 中文字幕日韩国产 | 区一区二区三区中文字幕 | 日韩二区三区在线观看 | 亚洲国产精品电影 | 最近免费中文字幕大全高清10 | 97电影手机版 | 欧美另类高潮 | av电影免费在线播放 | 成人黄色av网站 | 国产精品情侣视频 | 日韩一区二区三区免费视频 | 午夜av免费| 激情喷水 | 久久99偷拍视频 | 一区二区三区四区五区在线 | 激情五月播播久久久精品 | 349k.cc看片app | 精品国产乱码久久 | 免费看av在线 | 欧美性生活小视频 | 日韩欧美在线一区二区 | 国产精品尤物 | 亚洲免费成人av电影 | 亚洲国产999 | 特级西西www44高清大胆图片 | 一区中文字幕在线观看 | 国际精品久久久久 | 日韩在线一二三区 | 欧美日韩aaaa | av中文字幕免费在线观看 | 日日夜夜噜 | www.狠狠操 | 不卡av电影在线 | 国产伦精品一区二区三区高清 | 这里只有精品视频在线 | av丁香花| 91在线播放综合 | 婷婷激情在线 | 天天操操操操操操 | 在线观看免费 | 欧美日韩一级视频 | 国产999视频 | 丁香花在线观看视频在线 | 69亚洲乱 | 婷婷综合久久 | 日本久久免费电影 | 国产一级在线 | 高清不卡免费视频 | 伊人天天综合 | 91亚洲国产成人久久精品网站 | 久草网在线视频 | 免费在线观看日韩视频 | 亚洲蜜桃av | 夜夜爽88888免费视频4848 | 这里只有精品视频在线观看 | 色婷婷综合久久久中文字幕 | 视频在线观看91 | 国产91免费观看 | 亚洲精品理论片 | 亚洲综合情 | 亚洲精品久久久蜜臀下载官网 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 亚洲精品在线国产 | 日韩在线视频免费观看 | 亚洲精品免费在线观看视频 | 精品免费视频. | 五月天婷婷狠狠 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 狠狠色丁香久久综合网 | 视频在线在亚洲 | www.香蕉视频在线观看 | 肉色欧美久久久久久久免费看 | 在线黄色免费av | 麻豆 91 在线| 国产黄色一级片在线 | 最新av电影网址 | 日韩精品观看 | 中文字幕一区二区三区乱码不卡 | 日韩av片免费在线观看 | 国产精品福利久久久 | 免费视频久久久 | 日韩两性视频 | 狠狠狠色丁香综合久久天下网 | 欧美另类色图 | 91av视频网站 | 久久久久北条麻妃免费看 | 五月天堂网 | 中文字幕色综合网 | 在线观看中文字幕网站 | 在线免费观看视频 | 不卡视频在线看 | 国产黄免费在线观看 | 欧洲亚洲精品 | 91麻豆免费版 | 九九免费观看视频 | avove黑丝 | 国产高清视频在线 | 天天草夜夜 | 日韩中文字幕在线看 | 日韩av午夜在线观看 | 五月婷婷色 | 国产麻豆精品久久一二三 | 久久久久久免费视频 | 正在播放久久 | 国产精品毛片一区二区在线 | 婷婷四房综合激情五月 | 欧美激情精品久久久久久 | 国产男男gay做爰 | 综合网天天色 | 国产成人精品久久久久蜜臀 | 成人久久久精品国产乱码一区二区 | 精品国产福利在线 | 久久精品—区二区三区 | 夜夜骑日日操 | 一本色道久久精品 | 欧美日韩首页 | 免费毛片一区二区三区久久久 | 国产成人在线精品 | 91精品人成在线观看 | 一区二区免费不卡在线 | 国产精品国产精品 | 久久免费a | 国产中文字幕视频 | 日韩经典一区二区三区 | 青春草免费视频 | 人人超在线公开视频 | 性色av免费看 | 国产精品免费视频网站 | 三级黄色大片在线观看 | 一区二区三区在线不卡 | 色九色| 蜜臀av网站 | 国产黄色免费观看 | 波多野结衣视频在线 | 毛片精品免费在线观看 | 91精品啪在线观看国产线免费 | 亚洲天堂网在线视频观看 | 网站你懂的 | av在线播放网址 | 99精品视频免费在线观看 | 一区二区欧美日韩 | 黄色国产在线观看 | 国产亚洲欧洲 | 免费v片 | 国产在线国偷精品产拍 | 美女视频黄在线 | 丁香六月天婷婷 | av电影不卡在线 | 免费视频一区 | 正在播放一区 | 激情久久综合网 | 亚洲精品九九 | 国产品久精国精产拍 | 久久久久免费精品国产 | 成人欧美一区二区三区黑人麻豆 | 国产日韩欧美在线影视 | 天天色欧美 | 久草在线免费色站 | 日韩av一区在线观看 | 天天操天天操天天操天天 | 亚欧日韩成人h片 | 天天夜夜操 | 永久中文字幕 | 人人看人人 | 五月的婷婷 | 香蕉视频免费在线播放 | 国产精品岛国久久久久久久久红粉 | 91在线免费播放 | 91精品视频一区二区三区 | 婷婷色在线播放 | 国产女人18毛片水真多18精品 | 欧美精品国产综合久久 | 天天干天天搞天天射 | 欧美性色综合网站 | 婷婷在线综合 | 国产人成免费视频 | 色婷婷综合久色 | 久久精品九色 | 国产91对白在线播 | 久久这里只有精品视频99 | 色com| 免费高清国产 | 亚洲午夜精品电影 | 91精品视屏 | 亚洲欧美一区二区三区孕妇写真 | 国产中的精品av小宝探花 | 日韩天天干 | 国产中文字幕视频在线观看 | 2019天天干夜夜操 | 国产麻豆精品久久一二三 | 国产精品久久久久久久久久不蜜月 | 最新不卡av | 日韩黄色大片在线观看 | 国产精品美女久久久久久久 | 日韩av免费在线看 | 99久久国产免费看 | 精品字幕 | 久人人| av免费成人| 国产永久免费高清在线观看视频 | 99国产精品视频免费观看一公开 | 日韩一区二区三区高清在线观看 | 日韩最新在线视频 | 日韩久久精品一区二区三区下载 | 欧美另类性 | 成人免费视频观看 | 亚洲伦理一区二区 | 毛片网站免费在线观看 | 99精品免费在线观看 | 日本在线观看一区 | 狠狠地操 | 黄色av网站在线观看 | 免费69视频 | 日本黄色一级电影 | 国产在线观| 人成免费网站 | 欧美吞精 | www久久com| 性色av香蕉一区二区 | 精品视频在线视频 | 久久99热国产| 精品国产aⅴ麻豆 | 91黄色在线视频 | 天天操天天舔天天干 | 亚洲精品免费在线观看 | 亚洲欧美成人网 | 麻豆视频成人 | 亚洲一区二区视频在线 | 国产精品成人免费精品自在线观看 | 摸阴视频| 欧美一级视频在线观看 | 欧美91精品久久久久国产性生爱 | 久久国产美女 | 免费色视频| 天天色.com | 最近免费中文字幕mv在线视频3 | 曰韩精品 | 在线免费av网 | 亚洲激情av | 深爱五月激情网 | 黄色av电影一级片 | 一区二区三区 中文字幕 | 国内综合精品午夜久久资源 | 国产欧美日韩一区 | 国产精品永久在线 | 国产在线国偷精品产拍免费yy | 色天天综合久久久久综合片 | 免费久久网 | 亚洲综合欧美日韩狠狠色 | 国产福利在线 | 免费观看全黄做爰大片国产 | 成人一级免费视频 | 日韩高清国产精品 | 精品国产一区二区三区久久久蜜臀 | 在线导航av| 亚洲片在线观看 | 中文字幕视频观看 | 爱爱av网站 | 日韩高清精品免费观看 | 欧美 日韩精品 | 欧美日韩亚洲第一页 | 97电院网手机版 | 91av片| 在线黄色av | 成人免费 在线播放 | 一区久久久 | 最近日本字幕mv免费观看在线 | 欧美一区二区视频97 | 午夜国产福利在线观看 | 精品专区 | 色国产精品一区在线观看 | 91视频下载| 色就色,综合激情 | 免费男女网站 | 特黄色大片 | 亚洲理论影院 | 日日碰狠狠添天天爽超碰97久久 | 久久男人免费视频 | 亚洲天堂在线观看完整版 | 国产超碰在线观看 | 伊人天天综合 | 久艹在线观看视频 | 少妇高潮流白浆在线观看 | 国产美女被啪进深处喷白浆视频 | 亚洲成人软件 | 国产一二三区在线观看 | 在线欧美最极品的av | 国产在线最新 | 久草在线91| 欧美男男激情videos | 日本公妇色中文字幕 | 久久午夜精品影院一区 | 日韩国产在线观看 | 精品资源在线 | 狠狠色丁香久久综合网 | 久操操 | 国产高清福利在线 | 欧美一级片在线免费观看 | 五月婷婷在线播放 | 在线亚洲精品 | 激情婷婷久久 | 成人影片在线播放 | 亚洲一区精品人人爽人人躁 | 日韩乱码中文字幕 | 亚洲国产美女精品久久久久∴ | 男女激情网址 | 四虎免费在线观看视频 | 九色在线视频 | 99精品国产99久久久久久福利 | 国产精品丝袜久久久久久久不卡 | 天天天天天天干 | 久久国产欧美日韩精品 | 91精品播放 | 国产精品嫩草55av | 国产精品观看视频 | 久草久草在线观看 | 99久久精品国产免费看不卡 | 久久国产午夜精品理论片最新版本 | 91九色视频 | 日韩一区二区三区免费电影 | 国产一级片网站 | 91电影福利 | 久久久久成人精品 | 制服丝袜在线 | 国产在线最新 | 久久精品79国产精品 | 中国一级片免费看 | 国产一卡久久电影永久 | 国产成年免费视频 | 国产精品欧美精品 | 久久久国产99久久国产一 | 国产精品乱看 | av不卡免费在线观看 | 国产精品不卡视频 | www.婷婷色 | 日韩色综合 | 国产一级片播放 | 超碰国产在线观看 | 中文字幕一区二区三区久久 | 免费进去里的视频 | 久久爱影视i | 久久久精品国产一区二区电影四季 | 午夜久久影视 | 最新中文字幕在线资源 | 欧美日韩国产综合一区二区 | 免费看一级特黄a大片 | 亚洲 中文 在线 精品 | 国产尤物在线 | 99久久99久久精品国产片 | 超碰97久久 | 亚洲伦理中文字幕 | 日韩经典一区二区三区 | 亚洲黄色免费网站 | 99产精品成人啪免费网站 | 免费av看片 | 日本黄色片一区二区 | 极品美女被弄高潮视频网站 | 成人9ⅰ免费影视网站 | 亚洲精品乱码久久久久久蜜桃动漫 | 狠狠狠狠狠色综合 | 色婷在线 | 亚洲国产成人在线播放 | 中文超碰字幕 | 69久久夜色精品国产69 | 久久人网| 国内精自线一二区永久 | 91精品免费看 | 国产免费午夜 | 中日韩在线视频 | 天天操天天射天天插 | 国产成人一区二 | 69精品| 中文亚洲欧美日韩 | 99视频在线免费看 | 丝袜网站在线观看 | 一区二区三区免费在线观看视频 | 天天色天天干天天色 | 中文在线a∨在线 | 久久婷婷网| 日韩欧美视频一区 | 不卡的av在线 | www.成人久久| 久久久久看片 | 亚洲第一香蕉视频 | 久久男女视频 | 久久视频网 | 日韩a在线看 | 狠狠操狠狠干天天操 | 日韩黄色av网站 | 亚洲视频99 | 国产一级在线 | 日日爽天天爽 | 69性欧美| 国产一二三在线视频 | 午夜精品久久久久久久99水蜜桃 | 手机成人在线 | 五月婷久久 | 国产91精品欧美 | 中文字幕在线资源 | 久草网站 | 国产精品一区二区三区在线免费观看 | 日本中文字幕在线看 | 天天做天天爱天天爽综合网 | 黄色在线观看网站 | 麻豆国产精品va在线观看不卡 | 又黄又爽又色无遮挡免费 | 日韩视频在线观看视频 | 中文字幕最新精品 | 亚洲综合小说电影qvod | 日韩欧美久久 | 91视频91色 | 五月综合色 | 在线观看视频三级 | 久久精品视频观看 | www.69xx| 日韩免费一区二区 | 日韩中字在线观看 | 2018好看的中文在线观看 | 日女人电影 | 97国产精品亚洲精品 | 国产99久久久国产精品免费二区 | www亚洲国产 | 欧美日韩一区二区三区在线观看视频 | 亚洲妇女av| 国产三级精品三级在线观看 | 麻豆精品传媒视频 | av在线免费播放 | 午夜国产福利在线 | 91视频免费播放 | 国产视频在线观看一区二区 | 日本动漫做毛片一区二区 | 国产一区二区三区 在线 | 五月婷在线视频 | 国产精品久久久久久久久久免费 | 99视频在线免费观看 | 日韩不卡高清视频 | 久久国产露脸精品国产 | 美女国产免费 | 91麻豆产精品久久久久久 | 中文字幕在线观看三区 | 久久久久国产a免费观看rela | 成人av免费电影 | 麻豆视频免费观看 | 亚洲资源一区 | 六月激情久久 | 久久综合网色—综合色88 | 国产在线1区| av一级网站| 日韩午夜高清 | 中文字幕av一区二区三区四区 | 亚洲精品乱码久久 | 日韩一区二区三区高清在线观看 | 亚洲资源在线 | 天天射综合网站 | 看片网站黄| av在线影视| 国产成人1区 | 国产成人免费在线 | 狠狠色丁香婷婷综合最新地址 | 国产明星视频三级a三级点| 中文字幕色在线 | 日韩三级久久 | 久久激情视频 久久 | 亚洲精品乱码久久久久久蜜桃欧美 | 中文字幕在线观看91 | 亚洲dvd| 欧美动漫一区二区三区 | 亚洲色影爱久久精品 | 国产色久 | 国产最新在线观看 | 久久精美视频 | 99久久精品久久久久久动态片 | 国产999精品久久久久久绿帽 | 四虎免费av| 国产精品一区免费看8c0m | 国内精品在线观看视频 | 日本黄色免费大片 | 五月天婷婷在线视频 | 在线观看一级 | 精品99视频| 在线导航av | 丁香花中文字幕 | 亚洲成人二区 | 久久精品视频免费观看 | 在线欧美日韩 | 国产精品久久久久一区二区 | 一区二区av | 国产99re| 久久er99热精品一区二区 | www.久久成人 | 91麻豆免费视频 | 国产涩涩在线观看 | 91福利影院在线观看 | 午夜电影av | 久久久久久久久久久网 | 日本韩国精品在线 | 夜夜澡人模人人添人人看 | 成人在线观看日韩 | 九九热只有这里有精品 | 国产在线观看一 | 色com网| 亚洲国产人午在线一二区 | 91精品国产麻豆国产自产影视 | 亚洲国产精品视频在线观看 | 91中文视频| 欧美一级电影片 | 亚洲综合视频在线观看 | 日韩在线短视频 | 精品在线看 | 在线国产高清 | 国产亚洲精品成人av久久影院 | 91成人精品一区在线播放69 | 国产日本高清 | 国产黄色免费 | 国内精品久久久久久 | 狠狠色丁香| 在线视频亚洲 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 91亚洲精品久久久久图片蜜桃 | 蜜臀aⅴ精品一区二区三区 久久视屏网 | 精品国产一区二区三区久久 | 久久久久综合精品福利啪啪 | 国产高清在线不卡 | 欧美极度另类性三渗透 | 成人黄色在线电影 | 91精品国产综合久久福利 | 91精品在线播放 | 久久人人爽人人爽人人片 | 在线免费日韩 | 久久y | 黄色视屏在线免费观看 | 免费网站看av片 | 国产精品久久久久国产精品日日 | 91九色porny蝌蚪视频 | 亚洲综合五月 | 国产最新精品视频 | 久久超级碰 | 亚洲精品99久久久久久 | 亚洲香蕉在线观看 | 五月婷婷视频在线观看 | 香蕉视频在线免费 | 婷婷色综合色 | www.天天干 | 在线国产日韩 | 国产精久久久久久妇女av | 久久精品3 | 国产精品9999久久久久仙踪林 | 国产精品免费在线视频 | 人人爱人人舔 | 久久久久久久久久国产精品 | 五月天丁香综合 | 夜夜操狠狠干 | 国产视频中文字幕 | 国产 日韩 在线 亚洲 字幕 中文 | www.亚洲精品 | 狠狠干,狠狠操 | 麻豆视频大全 | 狠狠色香婷婷久久亚洲精品 | 丰满少妇对白在线偷拍 | 免费久久网 | 日韩视频一二三区 | 国产午夜精品一区二区三区 | 91香蕉视频黄 | 99热国产在线中文 | 日韩av高清在线观看 | av丝袜在线 | 亚洲精品乱码久久久一二三 | 亚洲91中文字幕无线码三区 | www.干| 天天操天天色天天射 | 日韩理论片在线观看 | 国产高清免费av | 激情深爱 | 摸阴视频 | 一区二区视频在线看 | 亚洲丁香久久久 | 一区二区三区免费在线观看视频 | 久久精品官网 | 亚洲黄色一级电影 | 狠狠狠狠狠操 | 99精品偷拍视频一区二区三区 | 91在线免费视频观看 | 国产一区二区高清视频 | 日本中文字幕在线看 | free,性欧美 九九交易行官网 | 99热精品视| 日本三级全黄少妇三2023 | 成片人卡1卡2卡3手机免费看 | 免费在线观看av网址 | 久久婷婷激情 | 精品影院一区二区久久久 | 国产福利91精品 | 91福利视频一区 | 久久精品播放 | 日韩免费| 中文字幕免费观看 | 久久综合精品国产一区二区三区 | bbb搡bbb爽爽爽 | 久久电影国产免费久久电影 | 国产小视频在线观看 | 久草网视频在线观看 | 久久综合之合合综合久久 | 啪啪免费观看网站 | 蜜桃视频在线视频 | 国产视频精品久久 | 国产精品久久一区二区三区不卡 | 国产精品人人做人人爽人人添 | 一区二区av| 日韩黄色免费看 | 亚洲香蕉在线观看 | 精品久久久久久国产91 | 国产午夜精品一区二区三区 | 99久久99久久精品免费 | 亚洲一本视频 | 国产一区在线视频观看 | 五月天最新网址 | 成片免费观看视频999 | 99精品久久久久 | 婷婷色中文 | 不卡的一区二区三区 | 天天色草| 激情视频免费在线 | 国产精品成人久久久久久久 | 天天操天天操天天操天天 | 日韩精品一区二区三区免费视频观看 | 日韩最新在线视频 | 视频一区二区视频 | 国产精品国产三级国产aⅴ入口 | 综合网中文字幕 | 99精品国产高清在线观看 | 精品国产视频在线观看 | 国产精品s色 | 91免费高清 | 国产午夜激情视频 | 91看片淫黄大片一级在线观看 | 在线观看视频一区二区 | 中文字幕免费高清av | 国产丝袜网站 | 蜜桃视频色 | 久久线视频 | 99精品黄色片免费大全 | 91高清完整版在线观看 | 中文字幕五区 | 91在线视频免费播放 | 婷婷久久久| 欧美日韩在线观看一区二区三区 | 国产日韩欧美在线看 | 国产不卡在线 | 丁香婷婷综合色啪 | 免费黄色在线播放 | 精品高清美女精品国产区 | www国产在线 | 激情五月婷婷丁香 | 少妇bbbb搡bbbb搡bbbb | av在线播放一区二区三区 | 51久久成人国产精品麻豆 | 欧美日韩一区二区三区在线观看视频 | 国产精品久久久久久久久久新婚 | 精品一区二区免费在线观看 | 日韩在线观看小视频 | 少妇精品久久久一区二区免费 | 在线观看mv的中文字幕网站 | 99av国产精品欲麻豆 | 天天射天天爱天天干 | 国产美女视频免费 | 麻豆网站免费观看 | 最新国产福利 | 波多野结衣视频一区二区 | 日韩女同一区二区三区在线观看 | 国产成人综 | 欧美国产日韩一区二区 | 中文字幕乱偷在线 | 久久艹欧美 | 久久99精品久久久久久 | 国产成人精品网站 | 久久久免费在线观看 | 欧美色一色| 日韩电影一区二区三区在线观看 | 黄色片视频在线观看 | 99热99re6国产在线播放 | 免费在线一区二区 | 国产精品免费视频观看 | 五月婷婷综合在线视频 | 91麻豆精品国产91 | 日日夜夜网| 99热国产精品 | 97免费视频在线播放 | 97综合视频 | www.色午夜,com | 国产在线毛片 | 91tv国产成人福利 | 日韩有码在线观看视频 | 国产精品久久久久国产精品日日 | 97精品国产91久久久久久 | 国产一级片网站 | 97国产精品一区二区 | 奇米影视777四色米奇影院 | 欧美综合干 | 日韩精品免费一区二区三区 | 成 人 黄 色视频免费播放 | 99精品视频精品精品视频 | 伊人中文网 | 免费成人在线网站 | 91成人精品国产刺激国语对白 | 久久亚洲精品国产亚洲老地址 | 97电影手机版 | 亚洲精品乱码久久久久久蜜桃动漫 | 中文字幕av在线电影 | 精品影院一区二区久久久 | 欧美精品在线视频 | 婷婷丁香色 | 一级黄色毛片 | 91视频最新网址 | 久久8| 婷婷在线免费 | 在线不卡的av | 狠狠干综合| 99精品在线免费在线观看 | 久久成人欧美 | 在线视频成人 | 久久精品综合视频 | 91免费版在线 | a色网站 | 国产精品久久久久久久久久久杏吧 | 成人国产网站 | 国产精品久久99综合免费观看尤物 | 午夜精品一区二区三区在线观看 | 天堂av最新网址 | 日本一区二区三区视频在线播放 | 国产一区私人高清影院 | 欧美性粗大hdvideo | 国内免费久久久久久久久久久 | 992tv在线观看 | 麻豆视频免费播放 | 在线看片a | 天天操夜夜曰 | 久久中文字幕视频 | 亚洲精品456在线播放第一页 | 日韩在线播放视频 | 国产一级视频 | 国产精品一区二区美女视频免费看 | 99在线精品免费视频九九视 | 亚洲午夜久久久影院 | 五月天久久婷 | 亚洲欧美日韩国产一区二区 | 国产一区二区免费在线观看 | 爱av在线网 | 在线看小早川怜子av | 99免费在线视频观看 | 97在线观看免费 | 四虎在线免费观看 | 手机av在线不卡 | www.久热 | 欧美天堂视频在线 | 精品国产电影一区 | 免费av在线播放 | 99产精品成人啪免费网站 | 久久精品久久综合 | 特级毛片aaa | 久久久.com | 久草在线观看视频免费 | 香蕉免费在线 | 骄小bbw搡bbbb揉bbbb | 久久精品在线视频 | 国产亚洲精品精品精品 | 欧美国产日韩一区 | 黄色一级在线免费观看 | 99久久精品免费看国产麻豆 | 国产福利电影网址 | 射久久久 | 国产成人一区二区三区 | 亚洲在线免费视频 | 欧美永久视频 | 国产一级一片免费播放放 | 日韩中文字幕网站 | 国产 日韩 在线 亚洲 字幕 中文 | 亚洲精品在线观看的 | 国产第一福利网 | 亚洲午夜精品一区二区三区电影院 | 亚洲精品成人av在线 | av免费在线观看网站 | 9999免费视频 | 人人看97 | 玖玖精品在线 | 亚洲黄色精品 | 久久久精华网 | 中文字幕日本电影 | 色狠狠久久av五月综合 | 午夜视频99 | 天天爽网站 | 日韩精品免费在线 | 十八岁以下禁止观看的1000个网站 | 92国产精品久久久久首页 | 中文在线免费一区三区 | 一区二区三区视频 | 亚洲精品午夜国产va久久成人 | 亚洲黄色大片 | 少妇做爰k8经典 | 国内外成人免费在线视频 | 色一级片 | 四虎影视成人精品 | 午夜精品一区二区三区在线观看 | 国产一二区精品 | 日韩91av | 六月丁香激情网 | 97色在线 | 97色涩| 免费合欢视频成人app | 黄色片软件网站 | 黄色片免费看 | 亚洲夜夜综合 | 国产高清在线观看 | 黄网站色欧美视频 | 国产又粗又猛又爽又黄的视频免费 | 亚洲专区欧美 | 中午字幕在线观看 | wwwwwww色| 亚州av网站 | 欧美日韩午夜爽爽 | 亚州黄色一级 | 亚洲精品中文字幕在线 | 亚洲欧美成人综合 | 久久精品一二区 | 欧美日韩电影在线播放 | 四虎成人免费影院 | 午夜三级毛片 | 特级西西444www大胆高清无视频 | 久久精品国产精品亚洲 | 国产精品一区二区免费 | 成人午夜在线电影 | 亚洲成人精品国产 | 日日操操| 日本久久成人 | av在线电影网站 | 亚在线播放中文视频 | free,性欧美 九九交易行官网 | 国产在线观看av | 伊人伊成久久人综合网小说 | 精品在线二区 | 狠狠狠色狠狠色综合 | 国产日本在线观看 | 天天躁天天躁天天躁婷 | 丁香5月婷婷久久 | 久久精品影片 | 成人网色 | 婷婷干五月 | 四虎在线视频 | 国产精品久久99精品毛片三a | 欧美人交a欧美精品 | 91在线一区二区 |