代码随想录四天 | LeetCode19.删除链表的倒数第n个节点 + LeetCode24_两两交换链表中的节点+LeetCode142 环形链表|| + LeetCode面试题 0207_链表相交

LeetCode19.删除链表的倒数第n个节点

这道题还是双指针的经典应用。如果要删除倒数第n个结点,让 fast 指针先移动 n 步,然后再让 slow 指针移动,这样在 fast 指针到达链表的尾部时候,就可以删除slow所指向的结点了。

但是思路是如此,实际的编码过程还有很多细节。

比如:我们在链表中删除删除节点,我们需要知道他的前驱结点,然后才能完成删除。所以在这里我们让 fast 先移动 n + 1 步,这样 slow 就指向了 要删除节点的前一个节点,方便我们操作。

代码如下:

    public ListNode removeNthFromEnd(ListNode head, int n) {
        //定义虚拟头结点
        ListNode dummyHead = new ListNode(head, -1);

        //定义快慢指针
        ListNode fastNode = dummyHead;
        ListNode slowNode = dummyHead;

        //只要让快慢指针相差 n 个结点即可
        for (int i = 0; i < n + 1; i++) {
            fastNode = fastNode.next;
        }
        
        //在fast指针到达链表的尾部时,slow指针最终指向要删除节点的前一个节点
        while (fastNode != null) {
            fastNode = fastNode.next;
            slowNode = slowNode.next;
        }
        
        //完成删除操作,让前一个节点指向前一个节点的下一个节点的下一个节点。
        slowNode.next = slowNode.next.next;
        return dummyHead.next;
    }

LeetCode面试题0207.链表相交

本题求的是两个链表交点节点的指针,要注意:我们要的是指针相等,而不是数值相等。

本题思路还是很简单的,我们需要只需要让两个链表的长度一致,然后一个一个的比较指针是否相等即可。如果相同就返回,如果不相同,就返回空。

代码如下:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode pointA = headA;
        ListNode pointB = headB;
        int lenA = 0;
        int lenB = 0;

        //求链表A的长度
        while (pointA != null) {
            lenA++;
            pointA = pointA.next;
        }

        //求链表B的长度
        while (pointB != null) {
            lenB++;
            pointB = pointB.next;
        }

        //重置一下子
        pointA = headA;
        pointB = headB;

        //让pointA成为最长链表的头,LenA为其长度
        if (lenB > lenA) {
            int tempLen = lenA;
            lenA = lenB;
            lenB = tempLen;

            //swap(pointA,pointB)
            ListNode tempNode = pointA;
            pointA = pointB;
            pointB = tempNode;
        }

        //求长度差
        int gap = lenA - lenB;
        //让pointA和 pointB 在同一起点上 (末尾位置对齐)
        while (gap-- > 0) {
            pointA = pointA.next;
        }

        //遍历pointA和pointB遇到相同则返回
        while (pointA != null) {
            if (pointA == pointB) {
                return pointA;
            }
            pointA = pointA.next;
            pointB = pointB.next;
        }

        return null;
    }

LeetCode24.两两交换链表中的节点

初始时,cur指向虚拟头结点,然后进行如下三步:

24.两两交换链表中的节点1

操作之后,链表如下:

24.两两交换链表中的节点2

看这个可能就更直观一些了:

24.两两交换链表中的节点3

代码如下:

    public ListNode swapPairs(ListNode head) {
        //定义虚拟头结点
        ListNode dummyHead = new ListNode(head, -1);
        //定义用于遍历的指针
        ListNode point = dummyHead;
        //定义三个用于保存的指针
        ListNode temp = null;
        //保存第一个结点的指针
        ListNode firstPoint = null;
        //保存第二个节点的指针
        ListNode secondPoint = null;       
        

        while (point.next != null && point.next.next != null) {
            //保存指针的下一个节点的下一个节点的下一个节点
            temp = point.next.next.next;
            firstPoint = point.next;
            secondPoint = point.next.next;

            point.next = secondPoint;
            secondPoint.next = firstPoint;
            firstPoint.next = temp;
            //将point向后移动,准备下一轮的交换
            point = firstPoint;
        }

        return dummyHead.next;
    }

LeetCode142.环形链表II

代码如下:

    public ListNode detectCycle(ListNode head) {
        //定义快慢指针
        //快指针一次走两步
        ListNode fastPoint = head;
        //慢指针一次走一步
        ListNode slowPoint = head;

        while (fastPoint != null && fastPoint.next != null) {
            fastPoint = fastPoint.next.next;
            slowPoint = slowPoint.next;
            //相遇了标识有环
            if (fastPoint == slowPoint) {
                //这时我们要找到环的入口
                ListNode index1 = head;
                ListNode index2 = fastPoint;

                while (index1 != index2) {
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1;
            }
        }

        return null;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值