链表

删除特定节点

ListNode* removeElements(ListNode* head, int val) {
        ListNode dummy(0, head);
        ListNode* cur = &dummy;
        while (cur->next) {//
            if (cur->next->val == val) {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;//比条件可以多一个next
                delete tmp;
            } else
                cur = cur->next;
        }
        return dummy.next;
    }

两两交换相邻节点

​ 在改变单链表时,优先改变上游的指针

ListNode* swapPairs(ListNode* head) {
        if (!head || !head->next)
            return head;

        ListNode dummy(0, head);
        ListNode* cur = &dummy;

        while (cur->next && cur->next->next) {
            ListNode* p1 = cur->next;
            ListNode* p2 = cur->next->next;
            cur->next = p2;//先改头->p2  cur-->p1-->p2-->other
            p1->next = p2->next;//在改p1->other
            p2->next = p1;//最后在p2->p1;
            cur = p1;
        }
        return dummy.next;
    }

合并有序链表

struct ListNode {
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        // 创建一个哑节点作为新链表的起点
        ListNode dummy(0);
        ListNode* curr = &dummy;  // 当前指针用于构建新链表

        // 同时遍历两个链表
        while (l1 && l2) {
            if (l1->val <= l2->val) {
                curr->next = l1;
                l1 = l1->next;
            } else {
                curr->next = l2;
                l2 = l2->next;
            }
            curr = curr->next;  // 移动当前指针
        }

        // 将剩余部分直接连接到新链表末尾
        curr->next = (l1 != nullptr) ? l1 : l2;

        // 返回合并后的头节点
        return dummy.next;
    }
};

环形链表

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

class Solution {
public:
    bool hasCycle(ListNode *head) {
        // 边界情况:空链表或只有一个节点且无环
        if (head == nullptr || head->next == nullptr) {
            return false;
        }

        // 初始化快慢指针
        ListNode *slow = head;
        ListNode *fast = head;

        // 快指针及其下一个节点都非空时继续循环
        while (fast != nullptr && fast->next != nullptr) {
            slow = slow->next;                  // 慢指针每次走一步
            fast = fast->next->next;            // 快指针每次走两步

            if (slow == fast) {
                // 快慢指针相遇,说明存在环
                return true;
            }
        }

        // 遍历结束未相遇,说明没有环
        return false;
    }
};

在有序链表中删除相同元素

​ 在链表的循环中, 判断条件一般是所有指针中最前面的指针

ListNode* deleteDuplicates(ListNode* head) {
        if (!head) {
            return head;
        }
        ListNode* cur = head;
        while (cur->next){
            if (cur->val == cur->next->val){
                ListNode *tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            }else{
                cur = cur->next;
            }
        }
        return head;
    }