24. 两两交换链表中的节点
主要思想就是一次移动两个节点,以及判断条件
并且使用虚拟头结点,会方便很多,要不然每次针对头结点(没有前一个指针指向头结点),还要单独处理
ListNode* swapPairs(ListNode* head) {
if(head == nullptr)
return nullptr;
ListNode* pre = new ListNode();
pre->next = head;
ListNode* cur = pre;
while(cur->next != nullptr && cur->next->next != nullptr)
{
ListNode* tmp1 = cur->next;
ListNode* tmp2 = cur->next->next;
cur->next = tmp2;
tmp1->next = tmp2->next;
tmp2->next = tmp1;
cur = tmp1;
}
return pre->next;
}
19.删除链表的倒数第N个节点
这里遇到了指针指向的问题,一开始定义快慢指针为
cur->next = head;
slow->next = head;
出现问题就是使用slow->next = slow->next->next;删除节点时,没有效果
用编译器查看内存可知,cur, slow, dummyHead是三块不同的内存
所以修改slow的next,无法影响dummyHead的next,也就无法删除节点了
之后定义快慢指针为,问题解决
cur = dummyHead;
slow = dummyHead;
实际上之前的定义方式,并没有起到指针的效果,而是相当于给链表添加了三个虚拟头结点。
后面的定义方式才是指针的效果,真正能取到链表中的值并进行有效的修改
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head == nullptr || n == 0)
return nullptr;
ListNode* Head = new ListNode(0);
ListNode* cur = new ListNode(0);
ListNode* slow = new ListNode(0);
Head->next = head;
cur = Head;
slow = Head;
// cur->next = head;
// slow->next = head;
for(int i = 0; i < n; i++)
{
if(cur->next != nullptr)
cur = cur->next;
else
return nullptr;
}
// cout<<cur->val<<endl;
// cout<<"***********"<<endl;
while(cur->next!= nullptr)
{
slow = slow->next;
cur = cur->next;
cout<<slow->val<<endl;
}
ListNode* node = slow->next;
slow->next = slow->next->next;
// delete node;
node = nullptr;
return Head->next;
}
面试题 02.07. 链表相交
注意到两个链表公共节点后的节点是一样的就行了
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA == NULL || headB == NULL)
return NULL;
ListNode* curA = headA;
ListNode* curB = headB;
int lenA = 0 , lenB = 0;
while(curA != NULL)
{
lenA++;
curA = curA->next;
}
while(curB != NULL)
{
lenB++;
curB = curB->next;
}
// cout<<lenA<<" "<<lenB<<endl;
int difflen = 0;
if(lenA > lenB)
{
difflen = lenA - lenB;
curA = headA;
curB = headB;
}
else
{
difflen = lenB - lenA;
curA = headB;
curB = headA;
}
for(int i = 0; i < difflen;i++)
curA = curA->next;
while(curA)
{
if(curA == curB)
return curA;
curA = curA->next;
curB = curB->next;
}
// cout<<curA->val<<endl;
return curA;
}
142.环形链表II
学以致用,靠自己想不出来的
ListNode *detectCycle(ListNode *head) {
if(head == NULL || head->next == NULL)
return NULL;
ListNode* fast = head;
ListNode* slow = head;
ListNode* node1 = new ListNode();
ListNode* node2 = head;
while(fast!= NULL && fast->next!= NULL)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
node1 = fast;
cout<<node1->val<<endl;
break;
}
}
// cout<<slow->val<<" "<<fast->val;
if(fast != slow)
return NULL;
while(node1 != node2)
{
node1 = node1->next;
node2 = node2->next;
}
return node2;
}