我在代码随想录|写代码Day4之24. 两两交换链表中的节点,面试题 02.07. 链表相交,19. 删除链表的倒数第 N 个结点,141. 环形链表,142. 环形链表 II

第一题:24. 两两交换链表中的节点

题目:

一刷 :

思路:

我本意是将各个结点储存起来但是发现不知道怎么储存结点就退二求其次,储存它的每个结点的值,其实我发现这个题目还是有问题的-----就是每个结点的值是不同的,而且每个结点是有序递增的,所以我的输入如下:

1.创建一个vector容器去储存我们的值。

2.用ou去统计链表长度,用于后面判断链表是奇数还是偶数

3.我们创建一个快慢指针(其实我们这题的本质还是快慢指针),

4.其中pre是虚拟头结点,cur是指针,tmo是用于存储指针的指针

5.然后我们进入循环我们移动我们的头指针,为什么是head?(留给大家思考下)

6.竟然循环后我们用判断我们当前结点是否为偶结点,如果是偶结点我们就将值加入到我们新创建的链表头结点后面,如果奇数我们就创建一个结点然后用tmp指向这个结点然后对这个结点进行操作。

7.最后返回我们的结点

错误分析:

错误展示:为什么会出现这样的错误?

其实这个错误是由指针越界操作造成的如果p本身就指向空,那么我们对空结点的next域怎么操作,换句话而言,本身空结点就没有next域。

这个是对上面情况的解决方案当无论无论p是否为空,只要p->next为空就跳出循环,这个我们本身没有因为while条件退出循环而是通过if语句来实现跳过,和我上面的代码意思相同写法不同,然后导致运行结果不同。

 问题解答:

因为我们要返回的节点不可能为头节点所以我们使用head可以节省一定空间

​​​​​第二题: ​​​​​​19. 删除链表的倒数第 N 个结点 

题目

思路分析:

 怎么样删除链表?删除链表常规思路分为下面的几个:

1.确定我们要删除结点的位置或者值

2.创建一个指针定位到要删除节点的前一个节点

3.对要删除节点的next域进行修改,让他指向我们要删除节点的下一节点。

但是上面的删除会出现一定的问题请指出(后面公布答案)

一刷代码 :

详细代码:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n){
        ListNode*dum = new ListNode(0);//虚拟头节点
        dum->next = head;//确定虚拟头节点的位置
        ListNode*fast = head;//快指针
        ListNode*slow = dum;//慢指针
        ListNode*cnt=head;//用cnt用来计数否则不知道要删除哪个节点
        int count=0;//对我们的链表进行计数
        while(cnt){//当我们的指针不为空我们就将指针后移
            cnt=cnt->next;//进行后移操作
            count++;
        }
        int tme = (count-n);//定位我们要删除的元素位置
        while(tme){
            fast = fast->next;//快指针进行移动
            if(fast==nullptr){//判断
                break;//如果我们快指针移动后不判断在移动我们就有可能
            }//遇到我们快指针当前指向为空然后我们慢指针指针我们快指针为空的位置即对为空指针的操作
            slow = slow->next;
            tme--;//计数,为什么不直接放while中因为会出现问题当coun为1为1就无法进行循环
        }
        if(fast!=nullptr){//判断如果空指针不为空那么对slow指针进行操作
            slow->next=fast->next;
        }else{
            slow->next=nullptr;//否则我们直接让slow指针为空即可
        }
        return dum->next;//返回我们的头结点因为我们要删除的元素可能是头结点所以我们要用虚拟头结点
    }
};

代码解析之方法讲解:

 详细解答放代码中了,我这里和大家讲解下方法:

1.双指针:

为什么我们这里要用双指针呢,什么是双指针?

双指针顾名思义,就是有两个指针,一般是一个fast指针,和一个slow指针,fast指针一般比slow指针快一倍,这样在某些情况才不会跳过一些情况,双指针可以用于区间范围确定,和相遇问题,双指针可以实现滑动窗口,然后双指针有时候可以代替循环回避双重for快,如果用for去写双指针那么循环条件为O(n2),双指针为如果O(n)

然后下面是双指针的基础操作:

1.定义一fast指针和一个slow指针都指针开始的位置

2.定义fast移动,不同的题目移动条件可能不同,然后确定slow的移动条件

3.fast指针和slow指针移动,当满足一定条件对数据进行操作。

详细例子:

比如在上面的题目中fast的移动规则为比slow快一个节点

slow每次移动一个节点,slow与fast同时移动

满足条件:

当fast指针指针指向我们要删除的节点对fast和slow指针操作

2.虚拟头节点

当我们有了虚拟头节点我们可对链表进行很多操作无论是删除,增加,查找都有用处

解答:

为什么会出现问题呢?其实如果我们是非头尾节点就不会出现问题?
如果我们要删除的是头节点就有可能会出现问题?
如果是头节点的删除,我们就存在边界问题,
当我们对第一个元素进行操作假如我们只有一个头节点我们会发生什么?
我们无法删除头节点!!
那么我们到尾节点呢,
我们数据域的next为空当我们去访问next为空的指针域的时候会出现问题
所以我们要对节点删除进行操作

第三题:  141. 环形链表 

 题目其实和上以道题一样只是题目要求不一样,我们这个题要求判断是否为循环链表

方法1 双指针:

 暴力破解:

 

 
第四题 : 142. 环形链表 II - 力扣(LeetCode)

题目:

 美好诗篇:

第五题: 面试题 02.07. 链表相交 - 力扣(LeetCode)

题目:

深情算法:

希望大家在写代码的时侯总带有美好

我写了很多的算法题发现有些题目,无论怎么换壳其实本质都差不多,而写算法题就是要打破,他们的外壳去发现本质所以数学要好至少牛顿数学,和一些方法要会。

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值