移出链表元素
lc203.移除链表元素
- 题目lc203
- 思路:注意这里的头节点也有val,所以分两种情况,头节点和非头结点
- 代码如下:
class Solution {
public:ListNode* removeElements(ListNode* head, int val) {if(head == nullptr){return head;}ListNode* temp;while(head && head->val == val){temp = head;head = head->next;delete(temp);}temp = head;ListNode* before_temp = head; while(before_temp && before_temp->next != nullptr){if(temp->val == val){before_temp->next = temp->next;delete(temp);temp = before_temp;}before_temp = temp;temp = temp->next;}return head;}
};
- 看了官方题解,思路:先加入一个头节点,这样每个节点的操作都一样
- 代码如下:
class Solution {
public:ListNode* removeElements(ListNode* head, int val) {ListNode* new_head = new ListNode(0, head);ListNode* temp = new_head;while(temp->next){if(temp->next->val == val){ListNode* delete_node = temp->next;temp->next = delete_node->next;delete(delete_node);} else{temp = temp->next;}}return new_head->next;}
};
lc206 反转链表
- 题目lc206
- 思路:三个指针,一个指向前一个节点,一个指向当前节点,一个指向后一个节点
- 代码如下:
class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode* pre = nullptr, *cur = head;ListNode* temp = nullptr;while(cur != nullptr){temp = cur->next;cur->next = pre;pre = cur;cur = temp;}return pre;}
};
lc24. 两两交换链表中的节点
- 题目lc24
- 同上,用三个指针交换,加入头节点,详细思考过程见代码
- 代码如下:
class Solution {
public:ListNode* swapPairs(ListNode* head) {if(head == nullptr){return nullptr;}ListNode* dummy_head = new ListNode(-1, head);ListNode* pre = dummy_head, * cur = head, *next = head->next;while(cur && next){cur->next = next->next;next->next = cur;pre->next = next;pre = cur;cur = cur->next;if(cur != nullptr){next = cur->next;}}return dummy_head->next;}
};
lc19. 删除链表的倒数第 N 个结点
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* dummy_head = new ListNode(-1, head);ListNode* fast = dummy_head->next, *slow = dummy_head;for(int i = 0; i < n; i++){fast = fast->next;}while(fast){fast = fast->next;slow = slow->next;}slow->next = slow->next->next; return dummy_head->next;}
};
面试题 02.07. 链表相交
class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {if(headA == nullptr || headB == nullptr){return NULL;}int lenA = 0, lenB = 0;ListNode* temp = headA;while(temp != nullptr){lenA++;temp = temp->next;}temp = headB;while(temp != nullptr){lenB++;temp = temp->next;}while(lenA > lenB){lenA--;headA = headA->next;}while(lenB > lenA){lenB--;headB = headB->next;}while(headA != nullptr && headB != nullptr){if(headA == headB){return headA;}headA = headA->next;headB = headB->next;}return NULL;}
};
lc142. 环形链表 II
- 题目lc142
- 思路
- 先通过快慢指针找到相遇点:快指针向前走2步,慢指针每次走一步,如果有环总会相遇,如果fast为空则没有环
- 再通过双指针找到入口点:这里需要一些简单的数学推导,设head到入口点距离为x,我们用p指针从head走到入口节点;设入口节点到相遇点(用q指针)距离为y,相遇点到入口点距离为z;两条约束式,slow走的距离:x + y,fast距离:x + y + n(y + z),因为多走n圈;第二条约束式:slow距离 * 2 = fast距离;最后得出x = (n - 1)(y + z) + z,用代码实现就是q指针从fast和slow相遇点出发,走n圈以及z的距离,就会和p指针从head出发在入口节点相遇
- 代码如下:
class Solution {
public:ListNode *detectCycle(ListNode *head) {ListNode* fast = head, *slow = head;while(fast != NULL && fast->next != NULL){fast = fast->next->next;slow = slow->next;if(fast == slow){ListNode *p = head, *q = fast;while(p != q){p = p->next;q = q->next;}return p;}}return NULL;}
};