目录
找到两个无环单向链表的第一个公共点
描述
输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
数据范围: n≤1000n
要求:空间复杂度 O(1),时间复杂度 O(n)
例如,输入{1,2,3},{4,5},{6,7}时,两个无环的单向链表的结构如下图所示:
可以看到它们的第一个公共结点的结点值为6,所以返回结点值为6的结点。
思路:先计算出两个链表的长度,计算差值。长链表遍历结点先向后移动差值个结点,再和短链表一起向后遍历,直到两个遍历结点的地址相同。
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
int l1=0,l2=0,a=0;//l1代表pHead1的长度,l2代表pHead2的长度,a代表长度差值
ListNode* p1=pHead1;
ListNode* p2=pHead2;
if(p1==NULL||p2==NULL) return NULL;//有一个为空
while(p1!=NULL){//计算p1链表长度
l1++;
p1=p1->next;
}
while(p2!=NULL){//计算p2链表长度
l2++;
p2=p2->next;
}
p1=pHead1;
p2=pHead2;
if(l1>l2){//如果l1大,则移动链表pHead1
a=l1-l2;
while(a>0){
p1=p1->next;
a--;
}
}
else if(l1<l2){//如果l2大,则移动链表pHead2
a=l2-l1;
while(a>0){
p2=p2->next;
a--;
}
}
while(p1!=NULL&&p2!=NULL&&p1!=p2){//一起向后移动
p1=p1->next;
p2=p2->next;
}
if(p1==NULL||p2==NULL) return NULL;//没有公共节点
return p1;
}
二叉搜索树转换成双向链表
描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示
数据范围:输入二叉树的节点数 0≤n≤10000 ,二叉树中每个节点的值 0≤val≤10000
要求:空间复杂度O(1)(即在原树上操作),时间复杂度 O(n)
注意:
1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构
4.你不用输出双向链表,程序会根据你的返回值自动打印输出
思路:利用中序遍历递归,找到每个结点的中序序列中的前结点和后结点作为左右结点。但在实际代码中,可只找到前序结点,即可完成前后结点的连接工作。
class Solution {
public:
TreeNode* pre=NULL;
void first(TreeNode* root){
if(!root) return;
first(root->left);//找到中序遍历中根结点的前序结点
root->left=pre;
if(pre) pre->right=root;
pre=root;//根结点作为右子树中序遍历第一个的前序结点
first(root->right);
}
TreeNode* Convert(TreeNode* pRootOfTree) {
if(!pRootOfTree) return NULL;
TreeNode* p=pRootOfTree;
while(p->left) p=p->left;//找到双向链表的第一个结点
first(pRootOfTree);
return p;
}
};
重点:一开始执着于找到左右结点,并分别进行双向连接,没有考虑到两个结点的前后关系就可以扩展到整个链表了。
判断是否是平衡二叉树
描述
输入一棵节点数为 n 二叉树,判断该二叉树是否是平衡二叉树。
在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树
平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
样例解释:
样例二叉树如图,为一颗平衡二叉树
注:我们约定空树是平衡二叉树。
数据范围:n≤100n,树上节点的val值满足 0≤n≤10000
要求:空间复杂度O(1),时间复杂度 O(n)
思路:分为自顶向下和自底向上两种方法。第一个从根结点着手,如果左子树和右子树之差大于1就不是平衡树,但递归是从下往上,所以需要额外的空间存储每个点的左右子树差,不满足题意。第二个是从叶子结点开始向上,通过改编求结点高度的递归函数可以得到。
class Solution {
public:
int high(TreeNode* root){
if(!root) return 0;
int l=high(root->left);
if(l==-1) return -1;//如果左子树不是平衡树
int r=high(root->right);
if(r==-1) return -1;//如果右子树不是平衡树
if(abs(l-r)>1) return -1;//如果不是平衡树
return max(l,r)+1;
}
bool IsBalanced_Solution(TreeNode* pRoot) {
return high(pRoot)!=-1;
}
};