Leetcode 24 两两交换链表中的节点
思想:其实找到每两个结点的操作步骤之后,就会发现这些步骤是循环的,其次,为了方便操作第一个节点,也要设置虚拟头节点。同时由于节点原来的next被更换后,原来指向的节点会被断开,所以要提前设置一个临时的指针指向原来的next节点。同时,如果交换之后如果只剩一个节点,那么这个节点就会被跳过。
代码:
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
// 实际交换两个点的操作上是循环的 只要一直交换就好了
ListNode* cur = new ListNode;
cur->next = head;
ListNode* newhead = cur; // 新的头结点
while (cur->next != nullptr && cur->next->next != nullptr) {
ListNode* first = cur->next;
ListNode* second = cur->next->next;
cur->next = second;
ListNode* temp = second->next;
second->next=first;
first->next = temp;
cur = cur->next->next;
}
return newhead->next;
}
};
Leetcode 19 删除链表的倒数第N个节点
思路:找出这个数是正数第几个就可以了 之后找到他的前一个节点 使其next域指向下下个节点
同时为了避免头节点的的特殊处理,设置一个虚拟头节点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//首先先找到倒数第n个节点是正数第几个
ListNode* newhead = new ListNode;//虚拟头节点
newhead->next=head;
ListNode* p = head;
int size=0;//链表元素个数
while(p != nullptr){
size++;
p=p->next;
}
int counter = size - n + 1;//计算该节点是正数第几个
if(counter<=0||counter>size) return nullptr;
p = newhead;
//找到该节点的前一个节点
for(int i=0;i<counter-1;i++){
p=p->next;
}
p->next=p->next->next;
return newhead->next;
}
};
Leetcode 面试题 02.07 链表相交
思路:只要看结尾是不是同一个节点就可以判断有没有交点,同时得出两个链表的长度。求出两个链表的长度之差diff,让长的那个链表从diff往后遍历,短的那个从头往后遍历。现在这两个链表剩下未访问的节点数相同,令他们同时往后遍历,遇到的第一个相同节点就是答案。
难点:想出来怎么解决这个问题,其实看到时间复杂度可以是o(n)的时候可以想到应该是需要靠遍历。
代码:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//只要看结尾是不是同一个节点就可以判断有没有交点
//同时 得出两个链表的长度
ListNode* p = headA;
ListNode* q = headB;
int lenA = 0,lenB = 0;
while(p!=nullptr){
p = p->next;
lenA++;
}
//lenA++;//此时最后一个节点并没有被算进去所以再加一次
while(q!=nullptr){
q = q->next;
lenB++;
}
//lenB++;//另一个同理
//最后返回了就返回p和q之中的任意一个就可以
//从短的那个链表的第一个节点开始看两个链表的节点是否相同
//不相同则同时后移
if(p==q){
p = headA;
q = headB;
if(lenA<lenB){
for(int i = 0;i<lenB-lenA;i++) q=q->next;
}
else{
for(int i =0;i<lenA-lenB;i++) p=p->next;
}
while(p!=q){
p=p->next;
q=q->next;
}
return p;
}
else return nullptr;
}
};
Leetcode 142 环形链表II
思想:利用快慢指针确定是否有环。如果fast和slow两个指针能够相遇,则有环。
根据最后一行等式,可以发现 x的长度 等于 两个指针相遇的点到环的入口加(n-1)个环的长度
所以只需要在这两个点设置指针index和index1就可以,他们相遇的地方就是环的入口。
代码:
class Solution {
public:
ListNode* detectCycle(ListNode* head) {
// 先判断有没有环
ListNode* fast = head;
ListNode* slow = head;
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
if (slow == fast) {
ListNode* index = head;
ListNode* index1 = fast;
while(index!=index1){
index = index->next;
index1 = index1->next;
}
return index;
}
}
return nullptr;
}
};