代码随想录算法训练营| 203. 移除链表元素,206.翻转链表

链表

203. 移除链表元素

链表的基础概念就不介绍了,直接看代码吧。

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
    struct ListNode * cur ,*pre;
    cur = head;
    while(cur){
        if(cur -> val == val){
            if(head == cur){
                cur = cur -> next;
                head = cur;
            }
            else{
                pre -> next = cur -> next;
                cur = cur -> next;
            }
        }
        else{
            pre = cur;
            cur = cur -> next;
        }
    }
    return head;   
    }
};

我们来逐步分析一下这段代码

 struct ListNode * cur ,*pre;
    cur = head;
    while(cur){
        if(cur -> val == val){
            if(head == cur){
                cur = cur -> next;
                head = cur;
            }
           

首先我们定义了两个struct LinskNode类型的指针,分别是 cur和 pre,一开始的时候,我们让cur = head,并进入循环。如果cur为空指针,那么就停止循环。
在循环的过程中,如果满足题目条件,那么再进行判断:
若head = cur ,说明首个结点data域中的值就跟目标值相等,这个时候要删除这个结点,那么只需要将head和cur统一向后移动一个结点。

如果第二个或后面的结点data域的值跟目标值相等,那么就让上一个结点的后继指针指向当前结点的后继指针所指向的结点,可以参考下图。
在这里插入图片描述

代码如下

else{
                pre -> next = cur -> next;
                cur = cur -> next;
            }

好了,现在已经处理完值相等的情况了,那么如果目前指针的val域的值跟题目给的值不相等呢?

 else{
            pre = cur;
            cur = cur -> next;
        }

移动pre 和 cur 就好啦。

最后返回head,这道题就做完了。

206.反转链表

跟上一道题差不了太多,做这类题,重点就是画图分析

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
    struct ListNode * pre,*cur,*temp;
    cur = head,pre = NULL;
    while(cur){
        temp = cur -> next;
        cur -> next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;
    }
};

一开始的时候cur在head处,也就是链表的最左端,由于是要翻转链表,那么翻转之后的链表的最后一个结点指向的一定是NULL,并且,一开始的时候cur所在的结点就是翻转之后的最后一个结点,所以翻转之前,我们要在cur的前面设置一个空指针,也就是NULL,我们让pre = NULL即可。
接着我们让cur结点的next指向前一个结点,对于第一个结点来说就是指向NULL,这就是翻转的操作。
当然,我们需要设置一个临时的temp来储存转换之前的cur的下一个结点,不然cur无法向后移动。(换句话说,cur向后移动的操作是靠temp完成的)。

707.设计链表

1.获取第n个结点的数值:
由于链表不能像数组那样直接访问第n个元素,所以就需要从头开始用while循环。每循环一次,n减一,并且将n放到while循环的循环条件当中,这样当循环停止的时候,cur指向的就是第n个结点了,这样访问第n个结点的数值就非常方便了。

2.头部插入结点:
首先我们要先开辟一个空间。为了方便,我们不妨设置一个虚拟结点,让这个虚拟结点指向第一个结点,插入的时候,将虚拟节点指向的结点赋给头部新插入结点指向的结点,(可能有点绕,可以参考上面给的图和思路),这个时候相当于在新的结点和原本的第一个结点之间连了一条线(画出来的图像上),然后将虚拟结点移动到新增的第一个结点的左边,也就是将新增的结点赋给虚拟结点的指向

void addAtHead(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        newNode->next = _dummyHead->next;
        _dummyHead->next = newNode;
        _size++;
    }

代码如上,我可能说的有点不清晰(啊啊啊我也是小萌新😭,我尽量说的清楚点啦❤️~)

3.尾部插入结点:
尾部插入就简单了,只需要先让cur指针寻找到目前最后一个结点,然后进行新增尾结点的操作。
新增尾结点的时候,我们可以将新增的结点赋给 cur -> next(哈哈,这样表示是不是好理解多咯~)

后面的内容我会在明天跟链表剩余的部分一起发,嗯,有什么写的不好的地方欢迎指出来呀

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值