剑指offer:面试题23:链表中环的入口,反转链表(附加题leetcode第92题)

链表中环的入口

题目:给定一个链表,返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环,则返回 null

主要思想:运用快慢指针

题解:分析题目就可以知道,首先第一步是先判断链表是否有环,用到快慢指针(快指针每次都比慢指针多走一步),当快慢指针重合时,即有环,返回其重合的节点。

第二步就是分析链表环中有多少个节点,因为环是闭合的,所以可以通过返回的环中节点来计算环有多少个节点n。

第三步就是,定义一个前指针和一个后指针,前指针先走n步,然后和后指针一起遍历,当两指针重合时,重合节点为环的入口节点。

ListNode *detectCycle(ListNode *head) {
        if(head == NULL || head->next == NULL) return NULL;
        ListNode *front = MeetingNode(head);
        if(front == NULL) return NULL;
        ListNode *behind = front;
        int n = 1;
        front = front->next;

        //计算环中节点的个数
        while(front != behind)
        {
            front = front->next;
            n++;
        }
        front = head;
        behind = head;
        for(int i = 0; i < n; i++)
        {
            front = front->next;
        }
        while(behind != front)
        {
            front = front->next;
            behind = behind->next;
        }
        return behind;
    }

    //判断链表是否有环存在
    ListNode *MeetingNode(ListNode *head)   
    {
        if(head == NULL || head->next == NULL) return NULL;
        ListNode *slow = head;
        ListNode *farst = head->next;

        while(farst != NULL)
        {
            if(slow == farst) return slow;
            slow = slow->next;
            farst = farst->next;
            if(farst == NULL) return NULL;
            else farst = farst->next;
        }
        return NULL;
    }

链表反转

题目:给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

题解:第一步,建立一个伪头指针,其下一个指针指向头指针(这能使得头指针能像其他中间节点一样处理),找到需要反转的链表部分的前部份和后部分,分辨用一个start指针和end指针记录。

第二步:反转链表,利用三个指针,一个是前指针front,另一个头指针head,最后一个是尾指针p

将头指针指向end,而头指针head的next指向front反向,最后head和p均向后移动。

最后:当p指针与end指针重合时,退出反转,start指针的next指向head,返回behead->next,即为反转后的指针。(注意释放申请的behead指针)

ListNode* reverseBetween(ListNode* head, int left, int right) {
        if(head == NULL || head->next == NULL || right == left) return head;
        ListNode *behead = new ListNode(0, NULL);
        behead->next = head;
        ListNode *start = head;
        ListNode *end = NULL;
        ListNode *p = head;
        int n = 1;
        while(n != right && p != NULL)
        {
            if(n == left - 1) start = p;
            n++;
            p = p->next;
        }
        if(p == NULL) end = NULL;
        else end = p->next;
        if(left == 1) start = behead;

        ListNode *front = start->next;
        head = front->next;
        front->next = end;
        p = head->next;
        while(p != end)
        {
            head->next = front;
            front = head;
            head = p;
            p = p->next;
        }
        head->next = front;
        start->next = head;
        head = behead->next;
        delete behead;
        return head;
    }

猜你喜欢

转载自blog.csdn.net/m0_63001277/article/details/127015964
今日推荐