DAY4 24.两两交换链表中的节点 19.删除链表的倒数第n个节点 02.07. 链表相交 142.环形链表

24、两两交换链表中的节点

题目链接

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

思路

本题刚开始看到没有什么思路,后来学习了代码随想录的讲解,同样应该使用双指针的解法。主要分为以下几个步骤:
代码随想录讲解
在这里插入图片描述
1、先定义一个虚拟头节点,并添加一个pre指针指向虚拟头节点,步骤一先使得pre.next指向head的下一个节点。
2、使得head.next.next指向head,也就是从2指向1。
3、从1指向3,但是这时候出现了一个问题,3号节点的地址已经丢失,无法连接,所以我们要提前对3号节点的地址进行存储。

代码实现

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummyNode = new ListNode(-1,head);
        ListNode pre = dummyNode;
        while(pre.next != null && pre.next.next != null){
            ListNode tmp = head.next.next;
            pre.next = head.next;
            head.next.next=head;
            head.next=tmp;

            pre = head;
            head=head.next;
        }

        return dummyNode.next;
    }
}

19、删除链表的倒数第n个节点

题目链接

19.删除链表的倒数第N个节点

思路

本题使用的也是快慢指针的思路,删除倒数第n个节点,就需要让快指针移动n步,然后再和慢指针一起移动,慢指针即指向待删除节点的前一个节点,将该节点删除即可。

代码实现

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummyNode = new ListNode(-1,head);

        ListNode fastIndex = dummyNode;
        ListNode slowIndex = dummyNode;

        for(int i = 0;i < n;i++){
            fastIndex = fastIndex.next;
        }

        while(fastIndex.next != null){
            slowIndex = slowIndex.next;
            fastIndex = fastIndex.next;
        }

        slowIndex.next = slowIndex.next.next;

        return dummyNode.next;
    }
}

面试题 02.07、链表相交

题目链接

面试题 02.07. 链表相交

思路

分别在两条链表上定义两个指针curA和curB,循环遍历求出两个链表的长度。让A代表较长的那条链表,并使得两条链表从尾部对齐。这时候让两条链表同时往后走,直到找到地址相同的节点返回,如果没有,则返回null。

代码实现

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA = headA;
        ListNode curB = headB;

        int lenA = 0;
        int lenB = 0;

        while(curA != null){
            lenA++;
            curA = curA.next;
        }

        while(curB != null){
            lenB++;
            curB = curB.next;
        }

        curA = headA;
        curB = headB;

        if(lenB > lenA){
            int tmpLen = lenA;
            lenA = lenB;
            lenB = tmpLen;

            ListNode tmpNode = curA;
            curA = curB;
            curB = tmpNode;
        }

        int gap = lenA - lenB;

        while(gap-- > 0){
            curA = curA.next;
        }

        while(curA != null){
            if(curA == curB){
                return curA;
            }
            curA = curA.next;
            curB = curB.next;
        }

        return null;
    }
}

142、环形链表

题目链接

142.环形链表

思路

最开始看到本题,没有任何思路,后来学习了代码随想录的解题方法。
代码随想录题解
本题的解题思路还是快慢指针,初始让快慢指针同时指向头节点,向链表后遍历,慢指针每次走一步,快指针每次走两步,快指针一定会在环内和慢指针相遇。当两个指针相遇时,环入口距离头节点为x,已走过相遇点距离为y,距离下一圈入口为z,相遇时,快指针走过的节点是慢指针的2倍,(x+y)*2 = n(y+z),两边同时去掉一个x+y,x = (n - 1) (y + z) + z,当n=1时,x=z,所以如果一个指针从head到环入口,和从相遇点到环入口是相等的,定义两个指针,使他们每次同时前进一步,最终的相遇点即为环的入口。

代码实现

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fastIndex = head;
        ListNode slowIndex = head;

        while(fastIndex != null && fastIndex.next !=null){
            slowIndex = slowIndex.next;
            fastIndex = fastIndex.next.next;

            if(fastIndex == slowIndex){
                ListNode index1 = fastIndex;
                ListNode index2 = head;

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

                return index1;
            }
        }
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值