LC 24 两两交换链表中的节点
1.递归法
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
//递归的终止条件,如果进行到链表为空或者链表只剩一个元素,则停止递归
if (head == nullptr || head->next == nullptr) return head;
ListNode *Next = head->next;
//递归处理所有节点
head->next = swapPairs(Next->next);
//Next交换到了head前面
Next->next = head;
return Next;
}
};
2.模拟法(虚拟头节点)
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode *virtualHead = new ListNode(0);//虚拟头节点
virtualHead->next = head;//为了便于操作,虚拟头节点要设置在head之前
ListNode *cur = virtualHead;
while (cur->next != nullptr && cur->next->next != nullptr) {
ListNode *temp1 = cur->next;
ListNode *temp2 = cur->next->next->next;
cur->next = cur->next->next;
cur->next->next = temp1;
cur->next->next->next = temp2;
cur = cur->next->next;
}
ListNode *res = virtualHead->next;
delete virtualHead;
return res;
}
};
个人觉得,递归法更好理解一些。虚拟头节点需要自己画图,才直观。
LC 19 删除链表的倒数第N个节点
1.虚拟头节点
这一题的虚拟头节点,快慢指针,比较好理解,也可以将倒数第n个转换为正数再去做。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//双指针,先建立虚拟节点指向头节点,定义快慢指针指向虚拟节点
//快指针先走n+1步
//快慢指针同时走,直到快指针走到末尾,此时慢指针指向倒数第n个节点的上一个节点,删除其next
ListNode *virtualHead = new ListNode(0);
virtualHead->next = head;
ListNode* r = virtualHead;
ListNode* l = virtualHead;
//快指针先走n + 1步
while ( n != 0 && r->next != nullptr) {
r = r->next;
n -= 1;
}
r = r->next;
while (r != nullptr) {
r = r->next;
l = l->next;
}
l->next = l->next->next;
return virtualHead->next;
}
};
2.将要删除的位置换算为整数第几个
同样,更直观的方法。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//转换为正数第几个
if (head == nullptr) return head;
//求出链表有几个元素
int listSize = 0;
ListNode *pos = head;
while (pos != nullptr) {
pos = pos->next;
listSize++;
}
if (n > listSize) return head;
//将倒数第几个的位置,转化为正数第几个
int deletePos = listSize - n;
if (deletePos == 0) return head->next;
ListNode *cur = head;
int i = 0;
//走到该位置的前一个元素
while (i < deletePos - 1) {
cur = cur->next;
i++;
}
ListNode *temp = cur->next;
cur->next = temp->next;
delete temp;
return head;
}
};
LC 面试题02.07. 链表相交
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int sizeA = 0;
int sizeB = 0;
ListNode *curA = headA;
ListNode *curB = headB;
while (curA != nullptr) {
sizeA++;
curA = curA->next;
}
while (curB != nullptr) {
sizeB++;
curB = curB->next;
}
//重置curA和curB
curA = headA;
curB = headB;
//保证sizeA更大
if (sizeB > sizeA) {
swap(sizeA, sizeB);
swap(curA, curB);
}
int gap = sizeA - sizeB;
//对齐
while (gap--) {
curA = curA->next;
}
while(curA != nullptr) {
if (curA == curB) return curA;
curA = curA->next;
curB = curB->next;
}
return nullptr;
}
};
LC 142 环形链表II
使用哈希表,暴力解。会更容易想到。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
unordered_set<ListNode*> st;
while (head != nullptr) {
if (st.count(head)) return head;
st.insert(head);
head = head->next;
}
return nullptr;
}
};