24. 两两交换链表中的节点(题目链接:力扣)
思路:有点类似于昨天的翻转链表指针的做法,也是要用到双指针和一个临时指针用来保存临时转换的指针。一个cur指针主要来操作当前转换的二元组、一个pre指针保存前项指针。
void swap(ListNode *pre, ListNode *cur)
{
if (cur != NULL && cur->next != NULL)
{
ListNode *tmp = cur->next;
cur->next = cur->next->next;
tmp->next = cur;
pre->next = tmp;
swap(cur, cur->next);
}
}
ListNode* swapPairs(ListNode* head) {
ListNode* tmpHead = new ListNode();
tmpHead->next = head;
swap(tmpHead, head);
return tmpHead->next;
}
19.删除链表的倒数第N个节点(题目链接:力扣)
思路:看到倒数我的第一想法就是用递归,从后往回计数,每次加1,加到等于n的时候就删除,这样就需要每次传两个指针(或者不嫌麻烦也可以只穿一个指针,只不过到时候要判断->next->next != NULL之类的了)。
int remove(ListNode* pre, ListNode* cur, int n){
if(cur == NULL){
return 0;
}
int cnt = remove(cur, cur->next, n);
if(++cnt == n){
pre->next = cur->next;
delete cur;
}
return cnt;
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* tmpHead = new ListNode();
tmpHead->next = head;
remove(tmpHead, head, n);
return tmpHead->next;
}
第二种,卡哥提供的双指针的做法(不得不感叹双指针是真行啊),让一个快指针先走n步,然后慢指针和快指针一起走,等到快指针走到链表尾了,慢指针指向的位置也就是倒数第n个了。
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* tmpHead = new ListNode();
tmpHead->next = head;
ListNode* slow = tmpHead;
ListNode* fast = tmpHead;
while(n-- > 0){
fast = fast->next;
}
fast = fast->next;
while(fast != NULL){
slow = slow->next;
fast = fast->next;
}
slow->next = slow->next->next;
return tmpHead->next;
}
面试题 02.07. 链表相交(题目链接:力扣)
思路:百思不得解,看了卡哥的解析才知道怎么做的,原来只需要先便利两个链表计数,然后根据元素个数的差值尾部对齐,然后开始找就行了,这样只要当指针的内容相同时就知道两个链表相交。
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int countA = 0;
int countB = 0;
ListNode* tmpA = headA;
ListNode* tmpB = headB;
while(tmpA != NULL){
countA++;
tmpA = tmpA->next;
}
while(tmpB != NULL){
countB++;
tmpB = tmpB->next;
}
tmpA = headA;
tmpB = headB;
if(countA < countB){
int gap = countB - countA;
while(gap-- > 0){
tmpB = tmpB->next;
}
}else{
int gap = countA - countB;
while(gap-- > 0){
tmpA = tmpA->next;
}
}
while(tmpA != NULL){
if(tmpA == tmpB){
return tmpA;
}
tmpA = tmpA->next;
tmpB = tmpB->next;
}
return tmpA;
}
142.环形链表II (题目链接:力扣)
思路:这题是真的有难度!没做过环形链表的根本就想不到这种方法(又是双指针的做法!)!我也是看完卡哥答案自己再手敲了一遍,过程稍微复杂,感兴趣的小伙伴可以去代码随想录看看。
ListNode *detectCycle(ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast != NULL && fast->next != NULL){
slow = slow->next;
fast = fast->next->next;
if(slow == fast){
ListNode* index1 = head;
ListNode* index2 = slow;
while(index1 != index2){
index1 = index1->next;
index2 = index2->next;
}
return index1;
}
}
return NULL;
}