算法训练营 Day 4

1、两两交换链表中的节点

#include <iostream>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int val) : val(val), next(nullptr) {}
};

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点,将不带虚拟头结点的链表转化为带虚拟头结点的链表
        dummyHead->next = head; 
        ListNode* cur = dummyHead;
        while(cur->next != nullptr && cur->next->next != nullptr) { //两者的顺序不能交换
            ListNode* tmp = cur->next; 
            ListNode* tmp1 = cur->next->next->next; 

            cur->next = cur->next->next;    
            cur->next->next = tmp;         
            cur->next->next->next = tmp1;   

            cur = cur->next->next; // cur移动两位,准备下一轮交换
        }
        head = dummyHead->next;
        delete dummyHead;
        return head;
    }
};

ListNode *initList() {
    return nullptr;
}

void insertEndList(ListNode *&head, int val) { //这里如果不用引用的话,要么传入二级指针参数,要么返回一个结构体指针
    ListNode *node = new ListNode(val);
    if (!head) {
        head = node;
    } else {
        ListNode *tmp = head; //保持头结点不动

        while (tmp->next)
            tmp = tmp->next;

        tmp->next = node;
    }
}

void printList(ListNode *head) {
    ListNode *cur = head;
    while (cur) {
        cout << cur->val << " -> ";
        cur = cur->next;
    }
    cout << "nullptr" << endl;
}

int main() {
    ListNode *head = initList();
    for (int i = 1; i <= 6; ++i)
        insertEndList(head, i);
    printList(head);

    Solution solution;
    ListNode *node = solution.swapPairs(head);
    printList(node);
}

2、删除链表的倒数第N个节点

利用快慢指针去解决

#include <iostream>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int val) : val(val), next(nullptr) {}
};

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode* slow = dummyHead;
        ListNode* fast = dummyHead;

        n++;
        while(n-- && fast != nullptr) //快指针要移动 n+1 次
            fast = fast->next;

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

        ListNode *tmp = slow->next;
        slow->next = slow->next->next;
        delete tmp;

        head = dummyHead->next;
        delete dummyHead; //防止内存泄露

        return head;
    }
};

ListNode *initList() {
    return nullptr;
}

void insertEndList(ListNode *&head, int val) { //这里如果不用引用的话,要么传入二级指针参数,要么返回一个结构体指针
    ListNode *node = new ListNode(val);
    if (!head) {
        head = node;
    } else {
        ListNode *tmp = head; //保持头结点不动

        while (tmp->next)
            tmp = tmp->next;

        tmp->next = node;
    }
}

void printList(ListNode *head) {
    ListNode *cur = head;
    while (cur) {
        cout << cur->val << " -> ";
        cur = cur->next;
    }
    cout << "nullptr" << endl;
}

int main() {
    ListNode *head = initList();
    for (int i = 1; i <= 6; ++i)
        insertEndList(head, i);
    printList(head);

    Solution solution;
    ListNode *node = solution.removeNthFromEnd(head, 3);
    printList(node);
}

3、链表相交

#include <iostream>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int val) : val(val), next(nullptr) {}
};

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { //两个链表有可能耦合的
        ListNode *curA = headA;
        ListNode *curB = headB;
        int lenA = 0, lenB = 0;
        while (curA) { // 求链表A的长度
            lenA++;
            curA = curA->next;
        }
        while (curB) { // 求链表B的长度
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        // 让curA为最长链表的头,lenA为其长度
        if (lenB > lenA) {
            swap(lenA, lenB);
            swap(curA, curB);
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap--)
            curA = curA->next;

        // 遍历curA 和 curB,遇到相同则直接返回
        while (curA) {
            if (curA == curB) //这里是指针相等,而不是值相等,
                return curA; 

            curA = curA->next;
            curB = curB->next;
        }
        return nullptr;
    }
};

ListNode *initList() {
    return nullptr;
}

void insertEndList(ListNode *&head, int val) { //这里如果不用引用的话,要么传入二级指针参数,要么返回一个结构体指针
    ListNode *node = new ListNode(val);
    if (!head) {
        head = node;
    } else {
        ListNode *tmp = head; //保持头结点不动

        while (tmp->next)
            tmp = tmp->next;

        tmp->next = node;
    }
}

void printList(ListNode *head) {
    ListNode *cur = head;
    while (cur) {
        cout << cur->val << " -> ";
        cur = cur->next;
    }
    cout << "nullptr" << endl;
}

int main() {
    ListNode *head1 = initList();
    for (int i = 1; i <= 5; ++i)
        insertEndList(head1, i);
    printList(head1);

    ListNode *head2 = initList();
    insertEndList(head2, 5);
    insertEndList(head2, 0);
    insertEndList(head2, 1);
    head2->next->next->next = head1->next->next;
    printList(head2);

    Solution solution;
    ListNode *node = solution.getIntersectionNode(head1, head2);
    printList(node);
}

4、环形链表II

#include <iostream>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int val) : val(val), next(nullptr) {}
};

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast != nullptr && fast->next != nullptr) {
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) {
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while (index1 != index2) {
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index1; // 返回环的入口
            }
        }
        return nullptr;
    }
};

ListNode *initList() {
    return nullptr;
}

void insertEndList(ListNode *&head, int val) { //这里如果不用引用的话,要么传入二级指针参数,要么返回一个结构体指针
    ListNode *node = new ListNode(val);
    if (!head) {
        head = node;
    } else {
        ListNode *tmp = head; //保持头结点不动

        while (tmp->next)
            tmp = tmp->next;

        tmp->next = node;
    }
}

void printList(ListNode *head, int n) {
    ListNode *cur = head;
    while (n--) { //循环n次
        cout << cur->val << " -> ";
        cur = cur->next;
    }
    cout << "nullptr" << endl;
}

int main() {
    ListNode *head = initList();
    for (int i = 1; i <= 5; ++i)
        insertEndList(head, i);
    insertEndList(head, 5);
    insertEndList(head, 0);
    insertEndList(head, 1);

    ListNode *cur = head;
    while (cur->next)
        cur = cur->next;
    cur->next = head->next->next->next;
    printList(head, 8);

    Solution solution;
    ListNode *node = solution.detectCycle(head);
    printList(node, 5);
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值