寒假刷题打卡第七天 | 链表

今天本来该继续学习算法思想,但是碰到了图的知识点,因为之前没有系统学过这部分,今天看着很吃力。由于今天状态不好,打算过段时间再来看吧,先看一点简单的链表。

  1. 找出两个链表的交点
    这是剑指offer上面的原题。官方解答给出了一个很有意思的方法。
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA == NULL || headB == NULL) //这个条件不能删除,
            return NULL;
        ListNode * curAN=headA;
        ListNode * curBN=headB;
        int endA=1, endB=1;
        while(curAN != curBN)
        {
            if(curAN->next == NULL && endA)  // 因为删除了的话操作空指针
            {
                curAN = headB;
                endA = 0;
            }
            else
                curAN = curAN->next;
            if(curBN->next == NULL && endB)
            {
                curBN = headA;
                endB = 0;
            }
            else
                curBN = curBN->next;
            
        }
        return curAN;
    }
};

如果只是判断两个链表是否存在交点,则可以直接比较两个链表的最后一个节点。
2. 翻转链表
用递归的方法实现。
写递归的代码之前一定要想清楚递归迭代的条件是什么。比如这道题,翻转一个链表,相当于翻转这个链表中某个值之后的子链表,并返回子链表的最后一个元素的地址。并把返回的值的next设置为curnode。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==NULL || head->next==NULL)
            return head;
        ListNode * newend=head;
        while(newend->next != NULL)
            newend = newend->next;
        reverseListCore(head)->next = NULL;
        return newend;
    }
    ListNode* reverseListCore(ListNode* curNode)
    {
        if(curNode->next==NULL)
        {
            return curNode;
        }
        reverseListCore(curNode->next) -> next = curNode;
        return curNode;
    }
};
  1. 并归合并链表
    很巧妙的递归。
  2. 删除排序链表中的重复元素
    刚开始写了一个很冗长的算法,耗时也很久。后面想到了双指针
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head==nullptr)
            return head;
        ListNode* behind=head;
        ListNode* front=head;
        // 这个地方不能写成ListNode* behind=head,front=head;
        int curVal=head->val;
        while(front != nullptr)
        {
            while(front != nullptr && front->val == curVal)
                front = front->next;
            behind->next = front;
            behind = front;
            if(behind!=nullptr)
                curVal = behind->val;
        }
        return head;
        
    }
};
  1. 删除链表的倒数第n个节点

注意这道题和剑指offer那道有点不一样。但是思路类似。

  1. 交换链表相邻元素
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        
        if(!head || !(head->next))
            return head;
        ListNode * cacheNode = head->next->next;
        ListNode* tempNode = head;
        head = head->next;
        head->next = tempNode;
        head->next->next = cacheNode;
        ListNode* revNode=head->next;
        ListNode* curNode=head->next->next;
        while(curNode && curNode->next)
        {
            cacheNode = curNode->next->next;
            tempNode = curNode->next;
            revNode->next = curNode->next;
            revNode->next->next = curNode;
            revNode->next->next->next = cacheNode;
            revNode = revNode->next->next;
            curNode = revNode->next;
        }
        return head;
    }
};
上一篇:每日一题力扣430


下一篇:二叉树的非递归(迭代)统一实现“前中后序遍历”详解