第二周心得体会

第二周心得体会

链表的修删节点

  1. 合并两个排序的链表

  2. 反转链表


合并两个排序的链表

输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。

数据范围

链表长度 [0,500]

样例
输入:1->3->5 , 2->4->5

输出:1->2->3->4->5->5

在这里插入图片描述



如图可以建立一个虚拟结点dummy,返回时只要返回dummy->next即可。同时定义一个指针cur来对dummy进行添加结点的操作。
使dummy中的结点递增排序只要让指针L1,L2遍历两个链表中的所有结点并用cur顺次连接所有结点。

在这里插入图片描述

cur选择下个结点时有两种情况:
L1中的数字大于L2
L2中的数字大于L1

解决方法为将数较小的节点接在cur的下一个结点并后移cur

在这里插入图片描述
以此类推遍历所有的节点后输出dummy->next.

代码见下图。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* merge(ListNode* l1, ListNode* l2) {
        ListNode* dummy=new ListNode(-1);
        ListNode* cur=dummy;
        while(l1&&l2)
        {
            if(l1->val>l2->val)
            {
                cur->next=l2;
                cur=l2;
                l2=l2->next;
            }else
            {
                cur->next=l1;
                cur=l1;
                l1=l1->next;
            }
        }
        if(l1) cur->next=l1;
        else cur->next=l2;
        return dummy->next;
    }
};

反转链表

定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。

数据范围
链表长度 [0,30]

样例
输入:1->2->3->4->5->NULL

输出:5->4->3->2->1->NULL


程序执行结果如图:

在这里插入图片描述

我们的目标是把每一个结点的指针指向对调。

我们可以用迭代递归的方法实现程序

迭代

我们可以定义一个指针p指向前一个结点,q指向后一个结点,x指向q的下一个结点。

  1. 将p,q的指向对调。
  2. p移到q,即下一个步骤的前一个结点上。
  3. q移到下一个结点。
  4. x保存q的下一个结点。

实现如图。

在这里插入图片描述

最后将第一个结点指向空。

代码如图:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
    ListNode* p=head;
    if(!head || !head->next) return head;
    auto q=p->next;
    while(q)
    {   
        auto x=q->next;
        q->next=p;
        p=q;
        q=x;
    }
    head->next=NULL;
    return p;
    }
};

递归

因为每一次while内执行的循环次数相同,所以可以用递归算法来解决问题。

先看一下每一次的执行过程:

  1. 改变指针的指向

  2. 移动指针,进行下一次相同操作

    在这里插入图片描述

    如图我们可以定义两个指针head,tail做如图的操作。

    代码如下:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* reverseList(ListNode* head) {
            if(!head || !head->next) return head;
            auto tail=reverseList(head->next);
            head->next->next=head;
            head->next=NULL;
            return tail;
        }
    };
    

代码模拟如图:
在这里插入图片描述
可以看到递归的部分只改变了head的指向,并没有改变反转链表的头节点tail的位置,通过头节点的逐层回归来改变原有指针的指向来实现反转的目标。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值