55链表中环的入口结点--56删除链表中重复的结点--57二叉树的下一个结点

55链表中环的入口结点

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

思路分析:我们需要确定这个环的信息,但是我们只有链表头结点。

  1. 定义两个节点fast和slow,fast向后走两步,slow走一步,如果存在环,这两个结点会相遇,而且相遇的节点一定在环上。
  2. 如果存在环,fast和slow相遇之后,可以统计出环的节点数目count。
  3. 然后再让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。

  1. 如果当前节点的val和下个节点的值相等,才需要删除,否则当前节点和prev节点向后移动。
  2. 当需要删除时候,我们将当前节点值记录下来,从当前节点开始向后删除,删除和当前相等的若干值为止。
/*
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&&current->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二叉树的下一个结点

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
在这里插入图片描述
我们看看中序遍历的特点,可以得出以下结论:

  1. 如果当前节点存在右子树,那么安装中序的规则,下一个节点应该是右子树的最左节点。
  2. 如果当前节点没有右子树,那么当前节点存在于某个祖先节点的左子树中。找当前节点是其父亲节点的左孩子的父亲节点。
/*
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;
    }
};

牛客网链接

发布了139 篇原创文章 · 获赞 55 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Vickers_xiaowei/article/details/89434743