代码随想录算法训练营第四天 | 24. 两两交换链表中的节点 | 19. 删除链表的倒数第 N 个结点 | 面试题 02.07. 链表相交

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

题意

题目链接
将链表节点两两交换

struct ListNode* swapPairs(struct ListNode* head) {
    struct ListNode *tmp = NULL, *cur = NULL;
    int a;

    cur = head;

    while (cur != NULL && cur->next != NULL) {
        tmp = cur->next;
        a = cur->val;
        cur->val = tmp->val;
        tmp->val = a;

        cur = tmp->next;
    }

    return head;
}

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

题意

删除链表的倒数第 N 个结点

一次遍历删除, 用到双指针. 因为要删除指定的节点, 所以要找到删除节点的前一个节点, 所以这个指针区间就被放大了1个, 所以用了虚节点, 将原来的链表长度扩大1, 就不需要判断边界条件了(比如链表长度为2, 要删除倒数第二个)

struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    int i = 0;
    struct ListNode *slow = NULL, *fast = NULL, *tmp = NULL, *new = NULL;
    
    new = (struct ListNode *)malloc(sizeof(struct ListNode));
    new->next = head;

    slow = fast = new;

    for (i = 0; i < n; i++) {
        fast = fast->next;
    }

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

    tmp = slow->next;
    slow->next = slow->next->next;
    free(tmp);
    head = new->next;
    free(new);

    return head;
}

面试题 02.07. 链表相交

题意

面试题 02.07. 链表相交

找到两个链表的相交位置, 也就是说两个链表用了相同内存节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *cura = NULL, *curb = NULL;
    int lena = 0, lenb = 0;

    cura = headA, curb = headB;

    while (cura != NULL) {
        lena++;
        cura = cura->next;
    }

    while (curb != NULL) {
        lenb++;
        curb = curb->next;
    }

    cura = headA;
    curb = headB;
    if (lena < lenb) {
        cura = headB;
        curb = headA;
        int tmp = lena;
        lena = lenb;
        lenb = tmp;
    }

    while (lena-- - lenb > 0) {
        cura = cura->next;
    }

    while (cura != NULL) {
        if (cura == curb) {
            return cura;
        }
        cura = cura->next;
        curb = curb->next;
    }

    return NULL;
}

142. 环形链表 II

题意

142. 环形链表 II

如果链表中存在一个环, 则返回这个环的入口

方法1

一开始想的是有环, 表示有两个节点的next都会指向同一个节点, 想法如下

/* 两个节点的next都指向同一个节点时, 这个被指向的节点就是环的入口
* 需要考虑整个都是环的情况, 所以使用虚节点
*/

不太好实现

方法2

快慢指针相遇

参考文章

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *slow = NULL, *fast = NULL;
    int flag = 0;

    slow = fast = head;

    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;

        if (slow == fast) {
            flag = 1;
            break;
        }
    }

    if (flag == 0) return NULL;

    fast = head;				// 从头开始时, 找环的入口
    while (slow != fast) {
        slow = slow->next;
        fast = fast->next;
    }

    return fast;
}
  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值