移出链表元素
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;
}
};