牛客 反转链表
思路1:
链表的长度总共有n项,假设第k+1到n项都反转完毕了,只需要更改第k+1的指针,让他指向第k项,然后让第k项指向空。
代码1:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(nullptr == pHead || nullptr == pHead->next)
return pHead;
ListNode *p = ReverseList(pHead->next);
pHead->next->next = pHead;
pHead->next = nullptr;
return p;
}
};
思路2:
用三个指针,将当前节点的next指针指向前一个指针即可。用
代码2:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
//ListNode *ReverseHead = nullptr;//用来记住反转之后的链表的头结点
ListNode *pNode = pHead;//用于指向当前节点
ListNode* pPre = nullptr;//用于指向当前节点的前一个节点
while(pNode != nullptr){
//if(nullptr == pNode->next)
//ReverseHead = pNode;
ListNode* pNext = pNode->next;//用于指向当前节点的后一个,必须记住。
pNode->next = pPre;
pPre = pNode;
pNode = pNext;
}
return pPre;
}
};
牛客 合并两个排序的链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路1:
见代码中的详细注释
代码2:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
//处理特殊情况
if(nullptr == pHead1)
return pHead2;
if(nullptr == pHead2)
return pHead1;
//合并后链表的头和尾
ListNode *head = nullptr;
ListNode *tail = nullptr;
//pHead1和pHead2都不为空的情况
while(pHead1 && pHead2){
//获得较小的节点做为新插入的节点
ListNode *p = pHead1->val < pHead2->val ? pHead1 : pHead2;
//更新位置
if(p == pHead1){
pHead1 = pHead1->next;
}
else
pHead2 = pHead2->next;
//插入第一个结点的情况
if(nullptr == head){
head = p;
tail = p;
}
//插入非第一个节点的情况
else{
tail->next = p;
tail = p;
}
}
//跳出while循环之后,处理其中的一个链表先结束的情况
if(nullptr == pHead1)
tail->next = pHead2;
else
tail->next = pHead1;
//返回合成的新链表的头结点
return head;
}
};
思路2:
见代码详细注释
代码2:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
//递归函数的出口
if(nullptr == pHead1)
return pHead2;
if(nullptr == pHead2)
return pHead1;
//链表的新的头结点
ListNode *head = pHead1->val < pHead2->val ? pHead1 : pHead2;
//判断是从哪个链表截出来的节点,并更新
if(head == pHead1)
pHead1 = pHead1->next;
else
pHead2 = pHead2->next;
//递归解决
head->next = Merge(pHead1,pHead2);
//返回最终的头结点
return head;
}
};
牛客 树的子结构
题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路1:
思路见代码注释
代码1:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
bool isSame(TreeNode* begin, TreeNode* beginSub)
{
//递归出口,beginSub为空的话,说明全部找完了
if(nullptr == beginSub){
return true;
}
//begin为空的话,没有完全匹配,返回false
if(nullptr == begin){
return false;
}
//有不相等的情况就返回false
if(begin->val != beginSub->val){
return false;
}
//递归
return isSame(begin->left,beginSub->left) &&
isSame(begin->right, beginSub->right);
}
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2){
if(pRoot1 == nullptr || pRoot2 == nullptr)
return false;
bool result = false;
//先找起始位置
if(pRoot1->val == pRoot2->val){
//判断它的左子树和右子树是否相等,调用函数判断
result = isSame(pRoot1, pRoot2);
}
//在左子树中找
if(!result){
result = HasSubtree(pRoot1->left, pRoot2);
}
//在右子树中找
if(!result){
result = HasSubtree(pRoot1->right, pRoot2);
}
return result;
}
};
牛客 二叉树的镜像
题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。
思路:
二叉树镜像本质是自顶向下进行左右子树交换的过程
代码:
/*
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(nullptr == pRoot)
return ;
TreeNode *temp = pRoot->left;
pRoot->left = pRoot->right;
pRoot->right = temp;
Mirror(pRoot->left);
Mirror(pRoot->right);
}
};