- 一. 根据前中序完成二叉树(不包含重复数据)的重建
- 1. 思路:
- 2. 下面代码中的递归语句理解:
- 3. 代码如下(另有相关代码注释帮助理解):
- 二.二进制计算一个数字里面有几个1
- 三. 输入一个单链表,输出倒数第K个节点
- 四. 每日小感慨
先序遍历第一个就是根节点,所以拿着前序的根节点在中序序列中找到根节点的位置。先找到根节点,进而划分左子树和右子树的前中序序列。划分如下:
(1)如何划分前序(根节点,左子树前序,右子树前序)
(2)如何划分中序(左子树中序,根节点,右子树中序)
中序序列中,根节点前面有几个值,在前序中,根节点后面几个就是左子树的相应的那几个节点。这样,我们就实现了数组的减小,从而获得root左子树的前中序序列,再将这一对再进行一次上述 *** 作,实现数组的进一步减小,进而实现最后的二叉树的重建。如下图所示:
像这样就可以一直递归下去……
2. 根据思路我们采用的是对于数组逐渐缩小的,分阶段进行划分的。所以我们要有对于下标的细致处理,所以我们需要前序的首尾和中序的首尾下标来进行。
class Solution
{
public:
TreeNode* reConstructBinaryTreeHelper(vector<int>&pre,int pre_start,int pre_end,vector<int>&vin,int vin_start,int vin_end)
{
if(pre_start>pre_end ||vin_start>vin_end)//递归出口
{
return nullptr;
}
//闭区间
TreeNode* root=new TreeNode(pre[pre_start]);
//阶段性处理时,根节点不止是下标为0的,而是每一次前序的首个元素。
for(auto i=vin_start;i<vin.end;i++)
//遍历中序找到根节点的位置
{
if(pre[pre_start]==vin[i])//说明在中序序列中找到了根节点的位置 [vin_start,i-1] i [i+1,vin_end]
{
//分别进行左右子树的重建
root->left=reConstructBinaryTreeHelper(pre,pre_start+1,pre_start + 1 + i-vin_start-1,vin,vin_start,i-1);
root->right=reConstructBinaryTreeHelper(pre,pre_start+i-vin_start +1,pre_end, vin,i+1,vin_end);
break;
}
}
//二叉树重建完毕
return root;
}
TreeNode* reConstructBinaryTree(vector<int>pre,vector<int>vin)
{
//对于特殊情况的判断
if(pre.empty()||vin.empty()||pre.size()!=vin.size())
return NUll;
return reConstructBinaryTreeHelper(pre,0,pre.size()-1,vin,0,vin.size()-1);
//首次传的时候前序下标就是0,中序下标就是i+1.
}
}
二.二进制计算一个数字里面有几个1
记录整数中的1的个数,我们正常是和1按位与。但是我们不是和一个单独的1进行运算,要注意1的二进制形式前面全是0,虽然只是和最后一位按位与,其他全置为0而已。
考虑到命中的效率问题不推荐左移右移,比如0比较松散或者1比较集中。
所以推荐的算法就是和自己小一位的数字进行按位与的 *** 作,
x& x-1 直到结果为0,按位与了几次,就有几个1
下图为演示:
代码如下:
int Numberof1(int n)
{
int count=0;
while(n)
{
n&=(n-1);
count++;
}
return count;
}
三. 输入一个单链表,输出倒数第K个节点
由题可得,这是一个单链表,所以我们不能从后往前来数。
大家可能会有很多种想法,我来为大家推荐的是:
前后指针的思想,前面指针先走k步,然后前后指针同时继续跑。直到前指针到尾部,这时后指针就是倒数第k个节点。
ListNode FindKthToTail(ListNode head,int k)
{
if(head==null||k<0) return null;
ListNode front=head;
ListNode rear=head;
while(k>0&& front!=Null)//逻辑与的特点就是只要前面的条件k不符合就会直接跳出
{
front=front.next;
k--;
}
while(front!=Null)//只要能进来就说明k的值是合理的。
{
front=front.next;
rear=rear.next;
}
return k>0?null:rear;
//如果k的值不符合条件就说明k的值并不合理,所以返回空。
}
四. 每日小感慨
有的时候,我们会心血来潮给自己定很高的目标,这本没有错。但是计划赶不上变化,可能就会完不成目标而对自己的能力产生怀疑而心态爆炸。所以送大家一句话:
***完成有的时候要大于完美。***完成一件事会给予我们心灵上的肯定,进而有下一步的勇气。有的时候,“放自己一马”,并不是对于自身标准的降低,反而是将心中的傲气“泄气”,从而有更好的状态去面对未来。
好了,希望我的每日分享,能给你带来知识,以一种放松的状态充实自己!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)