算法训练营 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
    评论
邓俊辉教授是计算机科学与技术领域著名的教育家和研究者。他在清华大学担任教授,并负责计算机算法与理论方向的研究和教学工作。邓俊辉教授是中国计算机学会副理事长、国际著名科技出版社Springer中国系列丛书主编、IEICE China Communications主编、Journal of Internet Technology编委、《数据结构与算法教程》作者等。 在邓俊辉教授的指导下,他办了多次Dijkstra算法训练营,旨在培养学生对于算法学习的兴趣与能力。Dijkstra算法是一种用于图论中求解最短路径问题的经典算法,具有广泛的应用领域,如路由算法、网络规划和GPS导航系统等。在训练营中,邓俊辉教授通过讲解算法的原理和思想,引导学生进行编程实践和案例分析,帮助他们深入理解Dijkstra算法的应用场景与实际解决问题的能力。 邓俊辉教授所组织的Dijkstra算法训练营受到了广大学生的欢迎和积极参与。通过训练营的学习,学生不仅可以掌握Dijkstra算法的具体实现过程,还能了解算法设计的思路和应用的局限性。在训练营中,学生还可以与同学们进行交流和合作,共同解决实际问题,促进彼此的学术成长和人际交往能力的培养。 总之,邓俊辉的Dijkstra算法训练营为学生提供了一个系统、全面学习算法知识的平台,帮助他们培养解决实际问题的能力和思维方式。通过这样的培训,学生不仅能在学术领域取得更好的成绩,还可以为将来的职业发展打下坚实的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值