24-两两交换链表中的节点
题目链接:LeetCode-24
思想:创造虚拟头结点,先判是否为空,在链表前几个节点用指针标出,方便之后交换
时间复杂度:O(n) 空间复杂度:O(1)
/**
* 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;
while(cur -> next != nullptr && cur -> next -> next != nullptr){
ListNode* tmp = cur -> next;
ListNode* tmp1 = cur -> next -> next -> next;
cur -> next = cur -> next -> next;
cur -> next -> next = tmp;
cur -> next -> next -> next = tmp1;
cur = cur -> next -> next;
}
return dummyHead -> next;
}
};
19-删除链表倒数第N个节点
题目链接:LeetCode-19
思想:创造虚拟头结点和快慢指针,要删除第n个节点,就要知道他前一个节点的位置,故快指针与慢指针之间的距离为n+1,同时移动快慢指针,当快指针为空时候,再删除慢指针的后一个节点,这个节点就是倒数第n个节点
/**
* 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* fast = dummyHead;
ListNode* slow = dummyHead;
while(n-- && fast != NULL){ //快指针向后移动
fast = fast ->next;
}
fast = fast -> next;
while(fast != NULL){ //快慢指针同时向后移动
fast = fast -> next;
slow = slow -> next;
}
slow -> next = slow -> next -> next; //移除倒数第N个节点
//ListNode *tmp = slow -> next; 释放内存
//slow -> next = temp -> next;
//delete nth;
return dummyHead -> next;
}
};
142-环形链表
题目链接:LeetCode-142
思想:快慢指针,出发点、环形入口、环中相遇点,首先判断是否存在环
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* fast = head;
ListNode* slow = head;
while(fast != NULL && fast -> next != NULL){
slow = slow -> next;
fast = fast -> next -> next;
if(slow == fast){
ListNode* index1 = fast;
ListNode* index2 = head;
while(index1 != index2){
index1 = index1 -> next;
index2 = index2 -> next;
}
return index2;
}
}
return NULL;
}
};
链表相交
题目链接:LeetCode-02.07
思想:求两个链表交点节点的指针
时间复杂度:O(n + m) 空间复杂度:O(1)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
int lenA = 0, lenB = 0;
while (curA != NULL) { // 求链表A的长度
lenA++;
curA = curA->next;
}
while (curB != NULL) { // 求链表B的长度
lenB++;
curB = curB->next;
}
curA = headA;
curB = headB;
// 让curA为最长链表的头,lenA为其长度
if (lenB > lenA) {
swap (lenA, lenB);
swap (curA, curB);
}
// 求长度差
int gap = lenA - lenB;
// 让curA和curB在同一起点上(末尾位置对齐)
while (gap--) {
curA = curA->next;
}
// 遍历curA 和 curB,遇到相同则直接返回
while (curA != NULL) {
if (curA == curB) {
return curA;
}
curA = curA->next;
curB = curB->next;
}
return NULL;
}
};