24. 两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
思路
25题有一个通用的模板(出自讨论区的某位大神),可以直接套用在这道题中,具体来说就是先定义一个指向头部的指针p,并向链表后移2位,再将前面的链表进行反转。再使用递归函数不断进行反转链表,若最后剩余的没有反转的节点个数少于2个,则不进行操作。最后输出链表头结点即可。
代码
/**
* 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* p=head;
for(int i=0;i<2;i++){
if(p==NULL) return head;
p=p->next;
}
ListNode* pre = NULL;
ListNode* cur = head;
while(cur!=p){
ListNode* tmp=cur->next;
cur->next=pre;
pre=cur;
cur=tmp;
}
head->next = swapPairs(p);
return pre;
}
};
时间复杂度:O(n)
19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第
n
个结点,并且返回链表的头结点。
思路
暴力一点的想法就是先使用一个指针从头到尾遍历,计算链表长度len,然后创建一个新指针,并移动len-n-1步,使其位于删除元素之前,然后进行删除操作就行了。
也可以使用双指针,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。
代码
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* virtualhead = new ListNode(0,head);
ListNode* fastindex=virtualhead;
ListNode* slowindex=virtualhead;
while(n--)
fastindex=fastindex->next;
while(fastindex->next!=NULL){
fastindex=fastindex->next;
slowindex=slowindex->next;
}
ListNode* tmp=slowindex->next;
slowindex->next=slowindex->next->next;
delete tmp;
return virtualhead->next;
}
};
时间复杂度:O(n)
面试题 02.07. 链表相交
给你两个单链表的头节点
headA
和headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回null
。
思路
用哈希表存储链表A中的所有节点,再对链表B进行遍历,并每次查询B的节点是否在哈希表中,若存在,则相交,并返回相交节点。若不存在,则返回空节点。
代码
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
unordered_set<ListNode*> set;
ListNode* cur=headA;
while(cur!=NULL){
set.insert(cur);
cur=cur->next;
}
ListNode* curr=headB;
while(curr!=NULL){
if(set.find(curr)!=set.end()) //发现相交元素
return curr;
curr=curr->next;
}
return NULL; //没找到,返回空集
}
};
时间复杂度:O(m+n),m,n分别为链表A和链表B的长度。
142. 环形链表 II
给定一个链表的头节点
head
,返回链表开始入环的第一个节点。 如果链表无环,则返回null
。如果链表中有某个节点,可以通过连续跟踪
next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果pos
是-1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改 链表。
思路
跟上题有些相似,使用哈希表来遍历存储链表中的节点,当出现重复节点时,说明到达了环的头部节点,输出第一个重复节点即可,若不存在重复结点,则输出空值。
代码
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* cur=head;
unordered_set <ListNode*> set;
while(cur){
if(!set.count(cur)){
set.insert(cur);
}
else return cur;
cur=cur->next;
}
return NULL;
}
};
时间复杂度:O(n)