【水滴计划 | 每日两题】:反转链表、两两交换链表中的节点

137 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情

1、写在前面

大家好,我是翼同学,这里是【水滴计划 | 刷题日志】

每日两题,拒绝摆烂。

2、内容

2.1、题目一:反转链表

链接:206. 反转链表 - 力扣(LeetCode)

(1) 描述

image.png

(2) 举例

image.png

image.png

image.png

(3) 解题

对于链表的反转,这里我们定义两个指针,一边遍历链表一边反转结点的指向。

代码如下:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *cur, *newHead, *tmp;
        cur = head;     // 将工作指针指向原来的头指针
        newHead = NULL; // 新的头指针初始化为NULL
        // 遍历链表
        while(cur != NULL) {
            // 先保存工作指针的下一个结点
            tmp = cur->next;
            // 将工作指针的下一位结点指向新的头指针
            cur->next = newHead;
            // 更新头指针
            newHead = cur;
            // 更新工作指针
            cur = tmp;
        }
        // 最后返回新的头指针
        return newHead;
    }
};

image.png


2.2、题目二:两两交换链表中的节点

链接:24. 两两交换链表中的节点 - 力扣(LeetCode)

(1) 描述

image.png

(2) 举例

image.png

image.png

image.png

image.png

(3) 解题

首先创建一个虚拟头结点,将虚拟头结点指向头指针。

接着定义一个工作指针,指向虚拟头结点。

如果循环条件判断通过,则进入循环,此时进行两两交换。这里可以有三个步骤:

  1. 将工作指针指向需要交换的第二个结点;
  2. 使得第二个结点指向第一个结点;
  3. 最后将第一个结点指向下一轮可能需要交换的第一个结点。

示意图如下:

image.png

第一轮交换后:

image.png

实现代码如下:

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        
        ListNode* pHead = new ListNode(0);  // 虚拟头结点
        pHead->next = head;                 // 将虚拟头结点指向头指针 head
        ListNode* cur = pHead;              // 工作指针

        // 如果工作指针cur的后两个结点都不为 NULL,则进入循环
        while(cur->next != NULL && cur->next->next != NULL) {
            // 创建临时指针1,保存工作指针的下一个结点
            ListNode* t1 = cur->next; 
            // 创建临时指针2,保存工作指针的后面的第三个结点
            ListNode* t2 = cur->next->next->next;

            // 开始两两交换
            cur->next = cur->next->next;    // 步骤一
            cur->next->next = t1;           // 步骤二
            cur->next->next->next = t2;     // 步骤三

            // 将工作指针往后移动两位,继续进行循环条件判断
            cur = cur->next->next;
        }
        return pHead->next;
    }
};

image.png

3、写在最后

好了,今天就刷到这里,明天再来。