【无标题】

24. 两两交换链表中的节点

使previous为node1,进行下一轮循环

 

由于头节点就是第一个node1,所以要在头节点之前创建虚拟节点,作为第一个privous,返回时返回dummy的next

 

终止条件为node1或node2为NULL

题解

struct ListNode* swapPairs(struct ListNode* head){
    struct ListNode dummyNode;
    struct ListNode* previous;
    struct ListNode* node1;
    struct ListNode* node2;
    struct ListNode* nextNode;
    dummyNode.next = head;
    previous = &dummyNode;
    while((previous->next != NULL) && (previous->next->next != NULL))
    {
        node1 = previous->next;
        node2 = node1->next;
        nextNode = node2->next;
        previous->next = node2;
        node2->next = node1;
        node1->next = nextNode;
        previous = node1;
    }
    return dummyNode.next;
}

 19.删除链表的倒数第N个节点  

题目来源:leetcode 题库 19. 删除链表的倒数第 N 个结点

创建fast、slow两个节点,fast和slow都从head节点顺着链表往后移动,只要fast比slow先走n步,当fast为NULL的时候,slow就是倒数第n个节点,此时将slow节点删除即可

  

由于要删除slow节点,需要获取前一个节点,可以新创建一个previous节点,记录slow的上一个节点,不过这样会多N步的时间复杂度(previous = slow, slow = slow->next)

可以让fast比slow先走n+1步,这样当fast为NULL时,slow->next = slow->next->next,即可将倒数第n个节点从链表移除

由于会有链表长度刚好等于n的情况,此时需要将链表头移除, 若fast从头节点出发,经过n步,刚到到达队尾的下一个节点NULL,slow比fast慢n+1,slow节点就在head节点之前,可以在头节点前创建虚拟节点,使slow从此出发

fast从head出发,往后走n步,若fast为NULL时,n步未走完,则没有倒数第n个节点,根据题意返回NULL

题解

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    struct ListNode dummy;
    struct ListNode* fast = head;
    struct ListNode* slow;

    dummy.next = head;
    slow = &dummy;

    while((n != 0) && (fast != NULL))
    {
        n--;
        fast = fast->next;
    }
    if(n != 0)
    {
        return NULL;
    }

    while(fast != NULL)
    {
        slow = slow->next;
        fast = fast->next;
    }
    slow->next = slow->next->next;
    return dummy.next;
}

 面试题 02.07. 链表相交 

题目来源 :leetcode 面试题 02.07. 链表相交

 两个链表若相交,则从相交节点之后的链表剩余长度一定相等

将两个链表从头到尾走一遍,获取链表长度,两个链表长度相减,得到长度差值,长度长的链表先移动该差值次数,之后两个链表一起移动,若第一次节点相同,则找到相交节点;没有相同节点,则两链表不相交

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    int lenA = 0, lenB = 0;
    struct ListNode * currA = headA;
    struct ListNode * currB = headB;
    struct ListNode * Ret = NULL;
    while(currA != NULL)
    {
        lenA++;
        currA = currA->next;
    }
    while(currB != NULL)
    {
        lenB++;
        currB = currB->next;
    }
    currA = headA;
    currB = headB;
    if(lenA > lenB)
    {
        lenA = lenA - lenB;
        while(lenA != 0)
        {
            lenA--;
            currA = currA->next;
        }
    }
    else
    {
        lenA = lenB - lenA;
        while(lenA != 0)
        {
            lenA--;
            currB = currB->next;
        }
    }
    if(currA == currB)
    {
        Ret = currA;
    }
    else
    {
        while((lenB != 0) && (currA != currB))
        {
            lenB--;
            currA = currA->next;
            currB = currB->next;
        }
        if(currA == currB)
        {
            Ret = currA;
        }
    }
    return Ret;
}

142.环形链表II

题目来源:leetcode 题库 142. 环形链表 II

参考详解:

 

创建fast、slow两个指针,都从head从发,fast每次移动2步,slow每次移动1步。

若链表中存在环,在fast不会为NULL,且fast一定会与slow在环上相遇,fast额外比slow多走了n圈。

slow走过的距离:x+y

fast走过的距离:x+n*(y+z)

2x+2y = x + n*(y+z)

x = n*(y+z) - y

一个指针从相遇点出发,一个指针从head出发,相遇在环形入口处

题解

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode * fast = head;
    struct ListNode * slow = head;
    struct ListNode * Ret = NULL;
    while((fast != NULL) && (fast->next != NULL))
    {
        fast = fast->next;
        fast = fast->next;
        slow = slow->next;
        if(fast == slow)
        {
            fast = head;
            while(fast != slow)
            {
                fast = fast->next;
                slow = slow->next;
            }
            Ret = fast;
            break;
        }
    }
    return Ret;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值