55链表中环的入口结点
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路分析:我们需要确定这个环的信息,但是我们只有链表头结点。
- 定义两个节点fast和slow,fast向后走两步,slow走一步,如果存在环,这两个结点会相遇,而且相遇的节点一定在环上。
- 如果存在环,fast和slow相遇之后,可以统计出环的节点数目count。
- 然后再让fast和slow从头结点开始走,fast先走count步,二者再次相遇时候的节点一定是环入口节点。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
//求出环中节点数目x,然后快节点先走x,相遇是时候就在环入口位置.
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode*fast=pHead,*slow=pHead->next;
while(fast!=slow&&fast!=nullptr&&slow!=nullptr)
{
slow=slow->next;
fast=fast->next;
if(fast->next!=nullptr)
fast=fast->next;
}
int count=1;
ListNode* go=fast->next;
if(fast==slow&&fast!=nullptr)
{
while(go!=fast)
{
go=go->next;
count++;
}
}
else
return nullptr;
fast=pHead,slow=pHead;
for(int i=0;i<count;i++)
fast=fast->next;
while(fast!=slow)
{
fast=fast->next;
slow=slow->next;
}
return fast;
}
};
56删除链表中重复的结点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。
- 如果当前节点的val和下个节点的值相等,才需要删除,否则当前节点和prev节点向后移动。
- 当需要删除时候,我们将当前节点值记录下来,从当前节点开始向后删除,删除和当前相等的若干值为止。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (!pHead){
return nullptr;
}
ListNode* ret = pHead;
ListNode* pre = nullptr, *current = pHead;
while (current) {
bool shoud_delete = false;
if (current->next&¤t->val == current->next->val){
shoud_delete = true;
}
if (!shoud_delete){
pre = current;
current = current->next;
}
else{
int val = current->val;
ListNode* pnext;
while (current && (current->val == val)) {
pnext = current->next;
delete current;
current = pnext;
}
if (pre == nullptr)
pHead = current;
else
pre->next = current;
}
}
return pHead;
}
};
57二叉树的下一个结点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
我们看看中序遍历的特点,可以得出以下结论:
- 如果当前节点存在右子树,那么安装中序的规则,下一个节点应该是右子树的最左节点。
- 如果当前节点没有右子树,那么当前节点存在于某个祖先节点的左子树中。找当前节点是其父亲节点的左孩子的父亲节点。
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode==nullptr)return nullptr;
if(pNode->right!=nullptr)//右子节点存在,右子节点的最左节点是下一个节点
{
pNode=pNode->right;
while(pNode->left!=nullptr)
pNode=pNode->left;
return pNode;
}
//找当前节点为的父亲节点的左孩子的父亲节点
while(pNode->next!=nullptr)
{
if(pNode->next->left==pNode)
return pNode->next;
pNode=pNode->next;
}
return nullptr;
}
};