24、两两交换链表中的节点
主要思路:伪代码
dummyhead= new node();
dummyhead->next = head;
cur = dummyhead;
while(cur->next!=NULL && cur->next->next!=NULL){
temp1 = cur->next;
temp2 = cur->next->next->next;
cur->next = cur->next->next;
cur->next->next = temp1;
temp1->next = temp2;
cur = cur->next->next;
}
return dummyhead->next;
}
C语言代码
struct ListNode *swapParis(struct ListNode* head){
//使用双指针避免中间变量
typedef struct ListNode ListNode;
ListNode *dummy = (ListNode*)malloc(sizeof(ListNode));
dummy->next = =head;
LisNode* cur = dummy;
while(cur->next!=NULL && cur->next->next!=NULL){
temp1 = =cur->next;
temp2 = cur->next->next->next;
cur->next = cur->next->next;
cur->next->next = temp1;
temp1->next = temp2;
cur = cur->next->next;
}
return dummy->next;
}
19删除链表的倒数第N个节点
主要思路
双指针的思想:先把快指针往前移动n+1步,再将慢指针和快指针同时移动,当快指针指向NULL时候,慢指针就指向了倒数第N-1个节点。
struct ListNode *removeNthFromEnd(struct ListNode *head,int n){
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->next = head;
dummy->val = 0;
struct ListNode *fast = head;
struct LisNode *slow = dummy;
for(int i=0,i<n;i++){
fast = fast->next;
}
while(fast){
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
head = dummy->next;
free(dummy);
return head;
面试题 02.07. 链表相交
主要思路【咋感觉有些问题这道题的例子】
双指针求解,分别将curA和curB指向链表A和链表B的头节点
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *l = NULL, *s = NULL;
int lenA = 0, lenB = 0, gap = 0;
// 求出两个链表的长度
s = headA;
while (s) {
lenA ++;
s = s->next;
}
s = headB;
while (s) {
lenB ++;
s = s->next;
}
// 求出两个链表长度差
if (lenA > lenB) {
l = headA, s = headB;
gap = lenA - lenB;
} else {
l = headB, s = headA;
gap = lenB - lenA;
}
// 尾部对齐
while (gap--) l = l->next;
// 移动,并检查是否有相同的元素
while (l) {
if (l == s) return l;
l = l->next, s = s->next;
}
return NULL;
}
142、环形链表2
主要思路:伪代码
根据快慢指针是否相遇来判断链表是否有环,快指针一次两个节点,慢指针一次一个节点,两者一定会相遇。
伪代码
fast=head;
slow = head;
while(fast!=NULL && fast->next!=NULL){
fast = fast->next->next;
slow = slow->next;
}
//先找到相遇的点是index1
if(slow==fast){
index1 = fast;
index2 = head;
//推理出环的入口就是x的值
//x=(n-1)(y+z)+z
//假设n=1时候,x=z,相当于从index1和head都出发一个节点
//相遇的地方就是环的入口
while(index1!=index2){
index1=index1->next;
index2 = index2->next;
}
return index2;
}
}
return NULL;
}
}
C语言代码
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* fast = head;
struct LisNode* slow = head;
//先找相遇的点
while(fast!=NULL && fast->next!=NULL){
fast = =fast->next->next;
slow = slow->next;
if(slow==fast){
struct LisNode *index1 = fast;
struct LisNode *index2 = head;
while(index1!=index1){
index1 = index1->next;
index2 = index2->next;
}
return index1;
}
}
return NULL;
}