# leetcode 刷题日志 2018-3-28

404. 左叶子之和

求所有左叶子结点之和
1. 递归法

空指针判断
有左子节点？是叶子结点？是的话更新value的值

int sumOfLeftLeaves(TreeNode* root) {
if(!root) return 0; // NULL
int value = 0;
if(root->left){ //左子节点
if(!root->left->left && !root->left->right) //是不是叶子结点？
value = root->left->val ;
}
return value + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
}
2.非递归法遍历寻找所有左叶子结点

int sumOfLeftLeaves(TreeNode* root) {
if(!root) return 0; //注意一定要处理空指针
int res = 0;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
root = q.front();
q.pop();
if(root->left){ //左子节点
q.push(root->left);
if(!root->left->left && !root->left->right){ //是否为叶子结点
res += root->left->val;
}
}
if(root->right){
q.push(root->right);
}
}
return res;
}


671. Second Minimum Node In a Binary Tree

题意：求二叉树第二小值，没有返回-1


int findSecondMinimumValue(TreeNode* root) {
if(!root) return -1;
int res = -1;
queue<TreeNode* > q;
q.push(root);
set<int> s;
while (!q.empty())
{
root = q.front();
s.insert(root->val);
q.pop();
if (root->left) {
q.push(root->left);
}
if (root->right) {
q.push(root->right);
}
}
if(s.size() < 2) res = -1;
else res = *(++s.begin());
return res;
}

102. 二叉树的层次遍历

二叉树层次遍历且每层输出


vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int> > res;
vector<int> tmp;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
int currentLevelTotalNum = 0;
while(!q.empty())
{
tmp.clear();
currentLevelTotalNum = q.size();
while(currentLevelTotalNum--){  //一层一循环
root = q.front();
tmp.push_back(root->val);
q.pop();
if(root->left){
q.push(root->left);
}
if(root->right){
q.push(root->right);
}
}
res.push_back(tmp);
}
return res;
}


107. 二叉树的层次遍历 II

vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int> > res;
vector<int> tmp;
stack<vector<int> >tmps;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
int currentLevelTotalNum = 0;
while(!q.empty())
{
tmp.clear();
currentLevelTotalNum = q.size();
while(currentLevelTotalNum--){  //一层一循环
root = q.front();
tmp.push_back(root->val);
q.pop();
if(root->left){
q.push(root->left);
}
if(root->right){
q.push(root->right);
}
}
tmps.push(tmp);
}
while(!tmps.empty()){
res.push_back(tmps.top());
tmps.pop();
}
return res;
}

637. 二叉树的层平均值

题意：求二叉树每层平均值(double)所组成的数组


vector<double> averageOfLevels(TreeNode* root) {
vector<double> res;
if(!root) return res;
queue<TreeNode* > q;
q.push(root);
int currentLevelTotalNum = 0, n = 0;
double tmpd;
while(!q.empty()){
currentLevelTotalNum = q.size();
n = currentLevelTotalNum;
tmpd = 0;
while(currentLevelTotalNum--){ //此层所有节点
root = q.front();
tmpd +=root->val;
q.pop();
if(root->left){
q.push(root->left);
}
if(root->right)
{
q.push(root->right);
}
}
tmpd /= n;
res.push_back(tmpd);
}
return res;
}


101. 对称二叉树

题意：给定一个二叉树，检查它是否是它自己的镜像（即，围绕它的中心对称）。


bool is(TreeNode* root1, TreeNode* root2){
if(!root1 && !root2) return true;
if(!root1) return false;
if(!root2) return false;
if(root1->val != root2->val){
return false;
}
return is(root1->left,root2->right) && is(root1->right,root2->left);
}
bool isSymmetric(TreeNode* root) {
if(!root) return true;
return is(root->left,root->right);
}


111. 二叉树的最小深度

题意：二叉树最小深度（从根节点到叶子结点的结点个数，包含两端）


int minDepth(TreeNode* root) {
if(!root) return 0;
if(!root->left && !root->right)
return 1;
int left,right;
if(root->left) left = minDepth(root->left);
else left = INT_MAX;
if(root->right) right = minDepth(root->right);
else right = INT_MAX;
return min(left,right) + 1;
}


104. 二叉树的最大深度

题意：最大二叉树深度

1.终结条件：
1. NULL 0
2. 叶子结点 1
2. 分别计算左右子树长度
3. 返回max(left,right)+1 加1是因为加上本结点

int maxDepth(TreeNode* root) {
if(!root) return 0;
if(!root->left && !root->right) return 1;
int left, right;
if(root->left) left = maxDepth(root->left);
else left = INT_MIN;
if(root->right) right = maxDepth(root->right);
else right = INT_MIN;
return max(left,right) + 1;
}


110. 平衡二叉树

题意：判断是否为平衡二叉树


//获取树的深度
int getDepth(TreeNode* root){
if(!root) return 0;
return max(getDepth(root->left),getDepth(root->right)) + 1;
}
//递归判断每个结点的子树是否满足长度只差不大于1
bool isBalanced(TreeNode* root) {
if(!root) return true;
if(abs(getDepth(root->left) - getDepth(root->right)) > 1){
return false;
}
return isBalanced(root->left) && isBalanced(root->right);
}


144. 二叉树的前序遍历 +1 2


vector<int> res;
vector<int> preorderTraversal(TreeNode* root) {
//递归
if(root){
res.push_back(root->val);
preorderTraversal(root->left);
preorderTraversal(root->right);
}   return res;
}

vector<int> preorderTraversal(TreeNode* root) {
//迭代
vector<int> res;
if(!root) return res;
stack<TreeNode*> s;
while (!s.empty() || root != NULL)
{
if (root) { //至最左
res.push_back(root->val);
s.push(root);
root = root->left;
} else { //左到尽头，往右走
root = s.top();
s.pop();
root = root->right;
}
}
return res;
}



94. 中序遍历二叉树 1+2


vector<int> inorderTraversal(TreeNode* root) {
stack< TreeNode* > s;
TreeNode * p = root;
vector<int> tmp;
while(!s.empty() || p!=NULL){
while(p){ //到最左端
s.push(p);
p=p->left;
}
if(!s.empty()){  //右展一次
p=s.top();
tmp.push_back(p->val);
s.pop();
p=p->right;
}
}
return tmp;
}



145. 二叉树的后序遍历 1 2 + 迭代法

//递归法

vector<int> res;
vector<int> postorderTraversal(TreeNode* root) {
if(root){
postorderTraversal(root->left);
postorderTraversal(root->right);
res.push_back(root->val);
}
return res;
}

//迭代法

vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if(!root) return res;
stack<TreeNode* > s;
TreeNode *cur = root, *pre = NULL;
s.push(cur);
// 栈中的顺序是后序遍历的反序，先压入根，再压入右结点，左结点
while (!s.empty())
{
cur = s.top();
if((!cur->left && !cur->right) || (pre && (cur->left == pre || cur->right == pre))) //叶子结点直接处理 || 刚刚处理完左右结点
{
res.push_back(cur->val);
pre = cur;
s.pop();
}
else{
if(cur->right){
s.push(cur->right);
}
if (cur->left)
s.push(cur->left);
}
}
return res;
}


617. 合并二叉树

/*

根节点都为空，return NULL
根节点都不为空，求和
根节点有一个空，补上
进一步分析左右子树

*/

TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if(!t1 && !t2) return NULL;
if (t1 && t2) {
t1->val += t2->val;
t2->val = t1->val;
}
else if (t1) {
t2 = new TreeNode(t1->val);
}
else if (t2) {
t1 = new TreeNode(t2->val);
}
t1->left = mergeTrees(t1->left,t2->left);
t1->right = mergeTrees(t1->right,t2->right);
return t1;
}


114. 二叉树转换链表

题意：二叉树转换链表；将所有结点编程右指针连接


//迭代版，前序遍历
vector<TreeNode*> preOrder2(TreeNode* root) {
vector<TreeNode*> res;
if(!root) return res;
stack<TreeNode*> s;
TreeNode* p = root;
while(!s.empty() || p)
{
while(p){   //一直往左
res.push_back(p);
s.push(p);
p = p->left;
}
if(!s.empty()){ //右展
p = s.top();
s.pop();
p = p->right;
}
}
return res;
}
// 注意只需保留头指针，指针传递，传递方保留着头指针，他顺着访问就是了
void flatten(TreeNode* root) {
if(!root) return ;
//前序遍历结果
vector<TreeNode*> preOrderV = preOrder2(root);
int len = preOrderV.size();
root->left = NULL;
root->right = NULL;
//链表形成
for(int i=0;i<len;i++)
{
root->right = preOrderV[i];
root = preOrderV[i];
root->left = NULL;
root->right =NULL;
}
}


112. 路径总和

/*

*/

bool hasPathSum(TreeNode* root, int sum) {
if(!root) return false;
if(root->val == sum){ //恰好有叶节点满足
if(!root->left && !root->right){
return true;
}
}
return hasPathSum(root->left,sum-root->val) || hasPathSum(root->right,sum-root->val);
}


113. 路径总和 II

经典递归回溯

vector<vector<int> >result;
vector<int> path;
// 经典递归回溯问题
void findPath(TreeNode* root, int sum) {
if(!root) return ;
if(root->val == sum && !root->left && !root->right ) { //find a path equal sum && It's a leaf node
path.push_back(root->val);
result.push_back(path); // find a path
path.pop_back(); //!!
return ;
}
path.push_back(root->val); // 经过节点压入
findPath(root->left, sum - root->val);
findPath(root->right, sum - root->val);
path.pop_back(); // 对与此节点的左右子树都已经处理完，弹出此节点 !
}
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> res;
if(!root) return res;
findPath(root, sum);
return result;
}


257. 二叉树的所有路径

/*

*/

vector<vector<int> >allPath; //所有路径
vector<int> aPath; //单条路径
// 经典递归回溯法求二叉树所有路径
void findPath(TreeNode* root) {
if(!root) return ;
if(!root->left && !root->right) { //leaf node
aPath.push_back(root->val);
allPath.push_back(aPath);   // a path
aPath.pop_back();
return ;
}
aPath.push_back(root->val);
findPath(root->left);
findPath(root->right);
aPath.pop_back();
}

vector<string> binaryTreePaths(TreeNode* root) {
vector<string> res;
if(!root) return res;
findPath(root);
int len = allPath.size();
string tmpS = "";
for (int i=0; i<len; i++) {
tmpS = std::to_string(allPath[i][0]);
for (int j=1; j<allPath[i].size(); j++) {   //形成路径字符串
tmpS += ("->" + std::to_string(allPath[i][j]));
}
res.push_back(tmpS);
}
return res;
}
`

posted @ 2018-03-30 00:42  kimsimple  阅读(189)  评论(0编辑  收藏  举报