JZ8 (m)二叉树的下一个结点
-
考察对二叉树结构的理解,下一个节点要么是右子节点的最左节点,要么是当父节点的右子节点不是自己时的父节点
-
复杂度:时间 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)
class Solution { public: TreeLinkNode* GetNext(TreeLinkNode* pNode) { if(!pNode) return nullptr; TreeLinkNode *p=pNode; if(!p->right){ TreeLinkNode *tmp=p; p=p->next; while(p){ if(p->right==tmp){ tmp=p; p=p->next; }else break; } }else{ p=p->right; while(p->left) p=p->left; } return p; } };
JZ28 (e)对称的二叉树
- 递归,二叉树对称:根节点值一样 && 左右节点值一样&&左节点的右子树和右节点左子树对称&&左节点的左子树和右节点的右子树对称
- 复杂度:时间
O
(
n
)
O(n)
O(n),空间
O
(
n
)
O(n)
O(n)(递归调用栈)
class Solution { public: bool isSymmetrical(TreeNode* pRoot) { return isSym(pRoot, pRoot); } bool isSym(TreeNode *a, TreeNode *b){ if(!a && !b) return true; if(!a || !b) return false; return a->val==b->val && isSym(a->left, b->right) && isSym(a->right, b->left); } };
JZ78 (m)把二叉树打印成多行
- 树的层次遍历,队列,套模板
- 复杂度:时间
O
(
n
)
O(n)
O(n),空间
O
(
n
)
O(n)
O(n)
class Solution { public: vector<vector<int> > Print(TreeNode* pRoot) { vector<vector<int> > ret; vector<int> ans; if(!pRoot) return ret; queue<TreeNode*> q; q.push(pRoot); while(!q.empty()){ int sz=q.size(); TreeNode *front; ans.clear(); while(sz--){ front = q.front(); q.pop(); ans.push_back(front->val); if(front->left) q.push(front->left); if(front->right) q.push(front->right); } ret.push_back(ans); } return ret; } };
JZ37 (h)序列化二叉树
-
树的遍历和建立
-
前序+中序重建二叉树&&层次遍历重建二叉树,用了第一个方法,层次遍历见题解
-
复用了JZ7 重建二叉树的代码
-
复杂度:时间 O ( n ) O(n) O(n),空间 O ( n ) O(n) O(n)
class Solution { public: void preorder(TreeNode *root, vector<int> &pre){ if(!root) return; pre.push_back(root->val); preorder(root->left, pre); preorder(root->right, pre); } void inorder(TreeNode *root, vector<int> &in){ if(!root) return; inorder(root->left, in); in.push_back(root->val); inorder(root->right, in); } TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { if(pre.empty()) return nullptr; int pivot = pre[0]; int i=0; for(;i<vin.size();++i){ if(vin[i]==pivot) break; } TreeNode *root=new TreeNode(pivot); vector<int> left_pre,right_pre,left_vin,right_vin; for(int j=0;j<i;++j){ left_pre.push_back(pre[j+1]); left_vin.push_back(vin[j]); } for(int j=i+1;j<pre.size();++j){ right_pre.push_back(pre[j]); right_vin.push_back(vin[j]); } root->left=reConstructBinaryTree(left_pre, left_vin); root->right=reConstructBinaryTree(right_pre, right_vin); return root; } char* Serialize(TreeNode *root) { stringstream ss; vector<int> pre,in; preorder(root, pre); inorder(root, in); for(int i=0;i<pre.size();++i){ ss<<pre[i]; ss<<' '; } ss<<"-1 "; for(auto x:in){ ss<<x; ss<<' '; } char *ret = new char[ss.str().size()+10]; strcpy(ret, ss.str().c_str()); return ret; } TreeNode* Deserialize(char *str) { string string(str); istringstream iss(string); vector<int> pre, in; int num; while(iss>>num){ if(num==-1) break; pre.push_back(num); } while(iss>>num) in.push_back(num); return reConstructBinaryTree(pre, in); } };
今天学到的知识
-
std::stringstream 使用string构建stringstream,可以很方便地处理字符串
不需要考虑int char float和string之间类型转换的问题
string = > => => stringstream : 构造函数,stringstream ss(str)
stringstream = > => => string : std::stringstream::str() -
-
返回值为
const char*
-
若要转换为char * 需要
char *c_str = new char[str.size()+10]; strcpy(c_str, str.c_str());
-
-
- list:
- 随机访问—— 不支持
- 插入或移除元素—— O ( 1 ) O(1) O(1)
- deque:
- 随机访问—— O ( 1 ) O(1) O(1)
- 在结尾或起始插入或移除元素—— O ( 1 ) O(1) O(1)
- 插入或移除元素—— O ( n ) O(n) O(n)
- list:
-
动态建立二叉搜索树网站:Binary Search Tree
-
用栈和循环代替递归(还没看):如何利用栈和循环替代递归