#Leetcode 24 两两交换节点#
题目: 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode *p_head = new ListNode;
p_head->next = head;
ListNode* cur = p_head;
while(cur->next && cur->next->next){
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;
}
return p_head->next;
}
};
简要思路:
- 设置一个虚拟头结点,以便于统一处理头结点和非头结点;
- 需要分长度为偶数和奇数的情况,分别对应两种边界;
- 沿着cur、cur->next、cur->next->next的顺序去更新,但要事先记录!
- 操作某个节点,应该使cur指向前一个节点!
#Leetcode19 删除倒数第N个节点#
上代码:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyNode = new ListNode;
dummyNode->next = head;
ListNode* fast = dummyNode;
ListNode* slow = dummyNode;
int i =0;
while(fast->next){
if(i < n){
fast= fast->next;
i++;
continue;
}
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return dummyNode->next;
}
};
思路: 找到倒数第N-1个节点。然后操作下一个节点。。这里有一个小trick,就是用两个指针向后跑,其实这个都没关系,找到就行。
#Leetcode02.07链表相交#
题意:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
代码:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//ListNode* dummyNodeA = new ListNode;
//ListNode* dummyNodeB = new ListNode;
//dummyNodeA->next = headA;
//dummyNodeB->next = headB;
ListNode* curA = headA;
ListNode* curB = headB;
int len1 =0,len2 = 0;
while(curA ){
len1++;
curA = curA->next;
}
while(curB ){
len2++;
curB = curB->next;
}
curA = headA;
curB = headB;
if(len2 > len1)
{
swap(len1,len2);
swap(curA,curB);
}
int gap = len1 - len2;
while(gap--){
curA = curA->next;
}
while(curA && curB){
if(curA == curB)
return curA;
else
{
curA = curA->next;
curB = curB->next;
}
}
return NULL;
}
};
思路:注意一点,如果有相交节点,应该是后几个都相同,那么其实位置就不都是head了!
还有一个就是使用swap,更方便,不用去重复代码在实现以便了。
#Leetcode142 循环列表#
链接: 循环列表
题意: 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
代码:
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast->next){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
ListNode* index1 = fast;
ListNode* index2 = head;
while(index1 != index2 ){
index1 = index1->next;
index2 = index2->next;
}
return index1;
}
}
return NULL;
}
};
思路:本题较为重要和复杂!
首先一点:判断是否有环,即两个指针,一个快指针、一个慢指针,最后若相遇,则表示会有环,不相遇,则没有环;
如果有环,下边去找到入口:这里边有一个数学推导,就不多说了,最后的结果应该是:
相遇位置设为index1,head处新设置index2,然后二者向后跑,相遇点即为入口。