leetcode——双指针技巧

版权声明:小能 https://blog.csdn.net/qq_43152052/article/details/88601808

1、环形链表

题目描述:
在这里插入图片描述
解题思路:
在环形的条件下快指针必定追上慢指针,快指针的移动速度可以是慢指针的n倍。

class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head==NULL||head->next==NULL)return false;
        ListNode *slow=head;
        ListNode *fast=head->next;
        while(fast!=slow)
        {
            if(fast==NULL||fast->next==NULL)return false;
            slow=slow->next;
            if(fast->next!=0&&fast->next->next!=0)
                fast=fast->next->next;
            else
                   return false;
        }
        return true;
    }
};

2、环形链表Ⅱ

题目描述:
在这里插入图片描述
**解题思路:**主要利用leetcode的链表地址由于是由低到高的变化的,如果有环则head->next一定小于head。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
    while(head)
        {
            if(head->next<=head)return head->next;
            head=head->next;
        }
        return NULL;
    }
};

3、 相交链表

题目描述:
在这里插入图片描述
解题思路:
都是利用互换遍历链表的方式来进行相遇的,第一轮指针指向短链表先走完,这就意味着它在第二轮走长的链表会慢下来,这时第一轮长链表的指针便会追上来。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
       ListNode *cursorA = headA;
        ListNode *cursorB = headB;
        if (!cursorA || !cursorB)
            return NULL;
        while (cursorA != cursorB)
        {
            if (!cursorA)                
                cursorA = headB;
            else  
            	cursorA = cursorA->next;
            if (!cursorB)
                cursorB = headA;
            else
                cursorB = cursorB->next;
        }
        return cursorA;

         /**========方法二,与方法一类似=========
        if(headA==NULL||headB==NULL)return NULL;
        ListNode *na=headA,*nb=headB;
        while(na!=nb){
        na==NULL?headB:na->next;//na走A链表到头后从B链表head开始继续走
        nb==NULL?headA:nb->next;//nb走A链表到头后从A链表head开始继续走
         }
        return na;//na/nb等于AB链表相交节点,AB链表不相交则为null
    }
	**/
}

4、删除倒数第n个结点

题目描述:
在这里插入图片描述
解题思路:
fisrt先走n步,然后带着指向头结点的second走L-n-1步,second到达被删除点的前一个结点。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode *first=head;
        while(n--!=0)
        {
            first=first->next;
        }
        if(!first)return head->next;
        ListNode *second=head;
        while(first!=NULL&&first->next!=NULL)
        {
           second=second->next;
            first=first->next;
        }
        if(second!=NULL&&second->next!=NULL)
         second->next=second->next->next;
        return head;
         /**
        ==============方法二=================
        ListNode *zero=new ListNode(0);
         zero->next=head;
        ListNode *fast=zero;
        ListNode *slow=zero;
         //将快指针放向前移动n次
        for(int i=1;i<=n+1;i++)
            fast=fast->next;
             //循环遍历链表直到快指针到达尾部
        while(fast!=NULL){
            fast=fast->next;
             slow=slow->next;
        }//此时slow的后继结点为要删除的倒数第n个结点
        slow->next=slow->next->next;
         return zero->next;
        **/
    }
    };

猜你喜欢

转载自blog.csdn.net/qq_43152052/article/details/88601808