今天星期六,四道题上强度了,又是奋起直追的一天!
LeetCode 24.两两交换链表中的节点
解题思路:按照惯例采用虚拟头结点,这样可以方便处理头结点为空的链表,省去判断过程。第一种方法为比较笨的方法,先判断这个链表处理的从虚拟节点开始,后面是否满足有两个够交换的节点。之后,建立三个临时节点,存下两个待交换的节点和一个交换完成后的衔接节点。之后按照交换顺序进行赋值。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode*dummyNode = new ListNode(0);
dummyNode->next = head;
ListNode*curr = dummyNode;
while(curr->next&&curr->next->next){
ListNode*tmp1 = curr->next;
ListNode*tmp2 = curr->next->next;
ListNode*tmp3 = curr->next->next->next;
curr->next = tmp2;
tmp2->next = tmp1;
tmp1->next = tmp3;
curr = curr->next->next;
}
return dummyNode->next;
}
};
方法二解题思路:和方法一类似,区别就是少记录一个中间节点,即原来的curr->next->next,因为该节点可以通过curr->next直接指向,故只保留其前后两个节点就行。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode*dummyNode = new ListNode(0);
dummyNode->next = head;
ListNode*curr = dummyNode;
while(curr->next&&curr->next->next){
ListNode*tmp1 = curr->next;
ListNode*tmp2 = curr->next->next->next;
curr->next = curr->next->next;
curr->next->next = tmp1;
tmp1->next = tmp2;
curr = curr->next->next;
}
return dummyNode->next;
}
};
LeetCode 19.删除链表的倒数第N个节点
解题思路:采用快慢指针,快指针比慢指针提前运动N+1个节点,为什么是N+1个节点,是因为要让慢指针最后停在要删除的节点的前一个节点,这样方便对删除的节点进行处理。之后,快慢指针一起向后运动,当快指针为NULL时,跳出循环,此时,慢指针对应的节点为,要删除的节点的前一个节点,即可对节点进行删除。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode*dummyNode = new ListNode(0);
dummyNode->next = head;
ListNode*fast = dummyNode;
ListNode*slow = dummyNode;
while(n--&&fast!=nullptr){
fast = fast->next;
}
fast = fast->next;
while(fast){
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return dummyNode->next;
}
};
LeetCode 02.07. 链表相交
解题思路:比较笨一点的方法是,将链表A的所有节点都存进一个哈希集合中,之后对链表B的所有节点进行判断,看链表B内的节点是否出现在哈希集合内,若出现,则两个链表有交点。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode*dummyNode = new ListNode(0);
dummyNode->next = headA;
ListNode*curr = dummyNode;
unordered_set<ListNode*>set;
while(curr->next){
curr=curr->next;
set.insert(curr);
}
dummyNode->next = headB;
curr = dummyNode;
while(curr->next){
curr = curr->next;
if(set.count(curr)){
return curr;
break;
}
}
return NULL;
}
};
LeetCode 142.环形链表
题目链接:LeetCode 142.环形链表Ⅱ
解题思路:和上一个解题思路类似,如果存在环形链表,对应的链表指针一定是相同的。故建立一个哈希集合,将所遍历的节点都存进哈希集合里,之后边存,边验证,看该节点是否在之前出现过,若出现过,则直接返回该节点。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode*dummyNode = new ListNode(0);
dummyNode->next = head;
ListNode*curr = dummyNode;
unordered_set<ListNode*>set;
while(curr->next){
curr = curr->next;
if(set.count(curr)){
return curr;
break;
}
set.insert(curr);
}
return NULL;
}
};
总结:
这两天学习了链表的相关知识,链表的存储和数组不同,链表存储空间不是相连的。之后学习了链表的经典题目,如虚拟头结点,自己构建链表并对链表进行操作,反转链表,链表的删除问题,以及链表的相交问题。