LeetCode222 Count Complete Tree Nodes
2015-08-07 21:22
555 查看
对于一般的二叉树,统计节点数目遍历一遍就可以了,但是这样时间复杂度O(n),一下就被卡住了。
这题首先要明白的是,我们只需要知道叶子节点的数目就能统计出总节点树。
想法1:
既然是完全二叉树,我肯定是从左子树开始看,如果左子树不完整,右子树就不用再遍历了。由此形成一个递归的搜索过程,先搜索左子树,如果不完整,直接停止搜索,统计完毕;否则,还要再搜索右子树。
这样就能避开完全搜索遍历整棵树,但是当树接近满树的时候实际上还是将整颗树遍历了一遍。
想法2:
完全二叉树不同于满树的一点是,我们只能肯定它的最左边那个叶子节点肯定是存在的(这里说存在不太准确,实际就把完全二叉树当满树看,然后那些不满的地方就认为是叶子节点不存在)。所以一颗完全二叉树的高度只需要一路向左就能求得。现在告诉你一颗完全二叉树可能不是满树,从根节点的角度,就要看,到底从哪开始不满的。
按照定义,不满的节点肯定在右边。如果我们求解根节点的右子树的高度=H - 1,说明左子树肯定是满的,不用再看了;否则,右节点高度 = H - 2,说明root->right的叶节点都缺了,右边不用再看了。
有没有发现这种想法使得我们几乎一次排除了一半的元素,所以这题有一个标签叫做binary search,因为感觉想法上很像。
这题首先要明白的是,我们只需要知道叶子节点的数目就能统计出总节点树。
想法1:
既然是完全二叉树,我肯定是从左子树开始看,如果左子树不完整,右子树就不用再遍历了。由此形成一个递归的搜索过程,先搜索左子树,如果不完整,直接停止搜索,统计完毕;否则,还要再搜索右子树。
这样就能避开完全搜索遍历整棵树,但是当树接近满树的时候实际上还是将整颗树遍历了一遍。
想法2:
完全二叉树不同于满树的一点是,我们只能肯定它的最左边那个叶子节点肯定是存在的(这里说存在不太准确,实际就把完全二叉树当满树看,然后那些不满的地方就认为是叶子节点不存在)。所以一颗完全二叉树的高度只需要一路向左就能求得。现在告诉你一颗完全二叉树可能不是满树,从根节点的角度,就要看,到底从哪开始不满的。
按照定义,不满的节点肯定在右边。如果我们求解根节点的右子树的高度=H - 1,说明左子树肯定是满的,不用再看了;否则,右节点高度 = H - 2,说明root->right的叶节点都缺了,右边不用再看了。
有没有发现这种想法使得我们几乎一次排除了一半的元素,所以这题有一个标签叫做binary search,因为感觉想法上很像。
int countNodes(TreeNode* root) { int height = 0; auto p = root; while(p != NULL){ height++; p = p->left; } if(height < 2) return height; int countLeaf = 0; int curHeight = height; while(root){ auto pr = root->right; int heightR = 0; while(pr != NULL){ heightR++; pr = pr->left; } if (heightR == 0){ countLeaf+= 1; break; } else if(heightR == curHeight - 1){ //we don't need to look at the left child any more //because it must be full countLeaf += (1 << (heightR - 1)); root = root->right; } else{ //we don't need to look at the right child any more //because there no leaf node root = root->left; } curHeight -= 1; } return countLeaf + (1 << (height - 1)) - 1; }
相关文章推荐
- 【leetcode每日一题】NO19.Remove Nth Node From End of List
- 将Visual Studio打造成为Node.js IDE
- npm常用命令->nodejs
- nodejs配置与入门
- node.js 事件
- node.js 数组
- (medium)LeetCode 222.Count Complete Tree Nodes
- node msgpack5 数据传输 简单实现
- nodejs之socket.io模块——实现了websocket协议
- log4js-Node.js中的日志管理模块使用与封装【转】
- 47. Element isSameNode() 方法
- 46. Element isEqualNode() 方法
- 42. Element hasChildNodes() 方法
- 38. Element cloneNode() 方法
- node js 调试
- nodejs之supervisor模块——提高nodejs调试效率
- Nodejs的Express完成安装指导
- node.js之Windows 系统下设置Nodejs NPM全局路径
- Leetcode_237_Delete Node in a Linked List
- Lettcode_237_Delete Node in a Linked List