代码随想录算法训练营|链表内容复习

链表内容复习

移除链表元素

203. 移除链表元素

分别删除目标值结点

点击查看代码
/**
 * Definition for singly-linked list.
 * 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* removeElements(ListNode* head, int val) {
        while (head != NULL && head->val == val) {
            ListNode* tmp = head;
            head = tmp->next;
            delete tmp;
        }
        ListNode* cur = head;
        while (cur != NULL && cur->next != NULL) {
            if (cur->next->val == val) {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            } else {
                cur = cur->next;
            }
            
        }
        return head;
    }
};

虚拟头结点

点击查看代码
/**
 * Definition for singly-linked list.
 * 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* removeElements(ListNode* head, int val) {
        ListNode* dummyHead = new ListNode(0);
        ListNode* cur;
        dummyHead->next = head;
        cur = dummyHead;
        while (cur != NULL && cur->next != NULL) {
            if (cur->next->val == val) {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            } else {
                cur = cur->next;
            }
        }
        return dummyHead->next;

    }
};

设计链表

707. 设计链表 707的代码之前的竟然通过不了了Σ(っ °Д °;)っ,我需要找一下原因

首先是错误原因找到了,deleteAtIndex函数的条件判断中,错误写成了if (index >= size - 1 || index < 0) return;,应该是if (index > size - 1 || index < 0) return;

这次对原文档中的错误进行了修正,补充了一些小错误的解决思路,这次发现对链表的实现又多了写些领悟

点击查看代码
class MyLinkedList {
public:
    struct LinkNode {
        int val;
        LinkNode* next;
        LinkNode(int val):val(val), next(NULL){}
    };

    MyLinkedList() {
        dummyHead = new LinkNode(0);
        size = 0;
    }
    
    int get(int index) {
        if (index > size - 1 || index < 0) {
            return -1;
        }
        LinkNode* cur = dummyHead->next;
        while (index--) {
            cur = cur->next;
        }
        return cur->val;
    }
    
    void addAtHead(int val) {
        LinkNode* newNode = new LinkNode(0);
        newNode->val = val;
        LinkNode* cur = dummyHead;
        newNode->next = cur->next;
        cur->next = newNode;
        size++;
    }
    
    void addAtTail(int val) {
        LinkNode* cur = dummyHead;
        while(cur->next != NULL) {
            cur = cur->next;
        }
        LinkNode* tail = new LinkNode(0);
        tail->val = val;
        cur->next = tail;
        size++;
    }
    
    void addAtIndex(int index, int val) {
        LinkNode* cur = dummyHead;
        if (index > size) return;
        while (index--) {
            cur = cur->next;
        }
        LinkNode* pre = new LinkNode(0);
        pre->val = val;
        LinkNode* next = cur->next;
        cur->next = pre;
        pre->next = next;
        size++;
    }
    
    void deleteAtIndex(int index) {
        if (index > size - 1 || index < 0) return;
        LinkNode* cur = dummyHead;
        while (index--) {
            cur = cur->next;
        }
        LinkNode* tmp = cur->next;
        cur->next = tmp->next;
        delete tmp;
        size--;
    }

private:
    int size;
    LinkNode* dummyHead;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

今天又把707写了一遍,又是报错没有找出来,最后发现是get函数写错了。在get函数中,cur的指向是LinkNode* cur = dummyHead->next;,dummyHead是虚拟头结点,其下一个结点才指向的是第一个结点,我说怎么所有结点前面多了一个0呢

反转链表

206. 反转链表 反转链表的题目用双指针很简单,注意最后返回的是pre指针而不再是head了。

双指针写法

点击查看代码
/**
 * Definition for singly-linked list.
 * 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* reverseList(ListNode* head) {
        ListNode* cur = head;
        ListNode* pre = NULL;
        ListNode* tmp;
        while (cur != NULL) {
            tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};

两两交换链表中的节点

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

感觉这个链表题的套路性比较强,按照之前的做法来一遍确实可以避免跟多问题。之前写的这个用的一个right指针指向了left->next,但是没有用虚拟头结点,这样一来,遇到[1,2,3,4]的时候,只能执行一遍,就没有办法翻转后面的[3,4]

class Solution {
public:
	ListNode* swapPairs(ListNode* head) {
		if (head == NULL || head->next == NULL) return head;
		ListNode* left = head;
		ListNode* right = left->next;
		cout << left->next->val << right->next->next->val << endl;
		while (left->next != NULL && left->next->next != NULL) {
			// cout << left->val << right->val << endl;
			int tmp = left->val;
			left->val = right->val;
			right->val = tmp;
			left = left->next->next;
			right = left->next;
			// cout << left->next->val << endl;
		}
		return head;
	}
};

于是,在给他加上了虚拟头结点之后,过啦!这种是直接两两交换链表中的结点的值

点击查看代码
/**
 * Definition for singly-linked list.
 * 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* swapPairs(ListNode* head) {
		if (head == NULL || head->next == NULL) return head;
		ListNode* dummyHead = new ListNode(0);
		dummyHead->next = head;
		ListNode* left = dummyHead;
		ListNode* right = left->next;
		// cout << left->next->val << right->next->next->val << endl;
		while (left->next != NULL && left->next->next != NULL) {
			// cout << left->val << right->val << endl;
			int tmp = left->next->val;
			left->next->val = right->next->val;
			right->next->val = tmp;
			left = left->next->next;
			right = left->next;
			// cout << left->next->val << endl;
		}
		return dummyHead->next;
	}
};

另外就是正常的之前写的k哥版代码如下,这种是直接定义了中间的链表指针来进行交换

点击查看代码
/**
 * Definition for singly-linked list.
 * 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* swapPairs(ListNode* head) {
        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode* cur = dummyHead;
        ListNode* tmp;
        ListNode* tmp1;
        while (cur->next != NULL && cur->next->next != NULL) {
            tmp = cur->next;
            tmp1 = cur->next->next->next;
            cur->next = tmp->next;
            cur->next->next = tmp;
            cur->next->next->next = tmp1;
            cur = cur->next->next;
        }
        return dummyHead->next;
    }
};

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

19. 删除链表的倒数第 N 个结点 看了下之前的思路,还是很巧的,用的是双指针,不过这次用的循环条件成了while (right->next != NULL)和之前意思一样

点击查看代码
/**
 * Definition for singly-linked list.
 * 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* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode* left = dummyHead;
        ListNode* right = dummyHead;
        while (n--) {
            right = right->next;
        }
        while (right->next != NULL) {
            left = left->next;
            right = right->next;
        }
        ListNode* tmp;
        tmp = left->next;
        left->next = tmp->next;
        delete tmp;
        return dummyHead->next;
    }
};

链表相交

面试题 02.07. 链表相交 这个题思路没有什么难的,写几遍基本就不会错了,代码实现很简单

点击查看代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int len1 = 0;
        int len2 = 0;
        ListNode* curA = headA;
        ListNode* curB = headB;
        while (curA != NULL) {
            curA = curA->next;
            len1++;
        }
        while (curB != NULL) {
            curB = curB->next;
            len2++;
        }
        int len;
        if (len1 > len2) len = len1 - len2;
        else {
            swap(headA, headB);
            len = len2 - len1;
        }
        curA = headA;
        curB = headB;
        // cout << len2 << len1 << endl;
        while (len--) {
            curA = curA->next;
        }
        while (curA != NULL && curB != NULL) {
            if (curA == curB) return curA;
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;

    }
};

环形链表Ⅱ

142.环形链表II 这道题是有两个问题,首先第一个是是否有环第二个是要得出环的入口。首先可以在草稿纸上画出那个环,之后这道题的核心就是\(x\)的距离等于\(n-1\)圈加上\(z\)的距离,代入\(n=1\)之后,得到\(x=z\)

逻辑搞明白了,代码就十分简单了

点击查看代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        // 首先判断是否有环
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast != NULL && fast->next != NULL) {
            fast = fast->next->next;
            slow = slow->next;
            if (fast == slow) {
                ListNode* index = fast;
                ListNode* index2 = head;
                while (index2 != index) {
                    index = index->next;
                    index2 = index2->next;
                }
                return index;
            }
        }
        return NULL;
    }
};

链表完结🌺🌺

posted on 2025-04-25 09:20  bnbncch  阅读(24)  评论(0)    收藏  举报