算法训练营第4天|LeetCode 24.两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题02.07相交 142.环形链表II 链表部分总结

今天星期六,四道题上强度了,又是奋起直追的一天!

LeetCode 24.两两交换链表中的节点

题目链接: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个节点

题目链接: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. 链表相交

题目链接: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;
    }
};

总结:

这两天学习了链表的相关知识,链表的存储和数组不同,链表存储空间不是相连的。之后学习了链表的经典题目,如虚拟头结点,自己构建链表并对链表进行操作,反转链表,链表的删除问题,以及链表的相交问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值