剑指offer(16~18)--合并两个有序的链表--树的子结构--二叉树的镜像

16、合并两个有序的链表

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

思路分析

先找两个链表中第一个节点数据较小的那个作新链表表头,然后只要两个链表都没走到空,就判断两个遍历链表的节点,较小的尾插到新链表。当有一个链表已经走到空了,就直接把另一个链表之后的数据尾插到新链表。
在这里插入图片描述
牛客网链接

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1==NULL)return pHead2;
        if(pHead2==NULL)return pHead1;
        ListNode*head=NULL,*list1=pHead1,*list2=pHead2,*list=NULL;
        if(list1->val<list2->val)//判断哪个链表的头结点作为新链表的头结点
        {
            head=list1;
           list1=list1->next;
        }
        else
        {
            head=list2;
            list2=list2->next;
        }
        list=head;//要记录下新链表头结点作为返回值,list用来遍历新链表
        while(list1&&list2)
        {
            if(list1->val<list2->val)//取小的
            {
                list->next=list1;
                list1=list1->next;
            }
            else
            {
                list->next=list2;
                list2=list2->next;
            }
            list=list->next;//成功给新链表添加一个节点
        }
        if(list1)
        {
            list->next=list1;
        }
        if(list2)
        {
            list->next=list2;
        }
        return head;
    }
};

17、树的子结构

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

思路分析

看到树的问题,首先想递归,因为好理解,要判断一颗小树是不是大树的一部分。有三种情况,一种是根节点就是小树的根节点,那么去判断小树的子孙节点,如果都是满足,就是true,第二种和第三种就是小树在大树的左右子树中。

如果递归到大树都为空了,那么肯定是false,如果大树的根节点值不等于小树根节点值,那么说明这各节点不能做小树的根节点,返回false。如果递归到小树为空,说明此时小树的祖先节点都符合,那么就到了递归出口;如果左右子树都满足条件,那么也是true,那么就到了递归出口。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        if(!pRoot1)return false;
        if(!pRoot2)return false;
        return (ChildLegal(pRoot1,pRoot2)||
                HasSubtree(pRoot1->left,pRoot2)||
                HasSubtree(pRoot1->right,pRoot2));
    }
    bool ChildLegal(TreeNode*p1,TreeNode*p2)
    {
        if(!p2)return true;
        if(!p1)return false;
        if(p1->val!=p2->val)return false;
        return ChildLegal(p1->left,p2->left)&&ChildLegal(p1->right,p2->right);
    }
};

牛客网链接

18、二叉树的镜像

在这里插入图片描述

思路分析4

这道题的递归实现很简单,就是交换左右节点,如果左右孩子,然后递归左右孩子,让左右孩子把它们各自的左右孩子再交换。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if(!pRoot)return;
        TreeNode*tmp=pRoot->left;
        pRoot->left=pRoot->right;
        pRoot->right=tmp;
        if(pRoot->left)
            Mirror(pRoot->left);
        if(pRoot->right)
            Mirror(pRoot->right);
    }
};

牛客网链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值