【链表part02】| 24.两两交换链表中的节点、19.删除链表的倒数第N个节点、02.07.链表相交、142.环形链表

目录

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

 ✿LeetCode19.删除链表的倒数第N个节点❀

✿LeetCode面试题 02.07. 链表相交❀

✿LeetCode142.环形链表||❀ 


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

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

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

【链表part02】| 24.两两交换链表中的节点、19.删除链表的倒数第N个节点、02.07.链表相交、142.环形链表_第1张图片

我发现我已经找到写链表题的秘诀了,就是画图模拟,这样真的可以让你的思路很清晰,如果直接看代码的话,可能一下就绕进去了,但是画图你可以自己操作指针指向哪,直到完成题目的要求,以下是我写的代码: 

public ListNode swapPairs(ListNode head) {
        if(head==null || head.next==null){
            return head;
        }
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode cur=dummy;
        while(cur.next!=null && cur.next.next!=null){
            ListNode temp1=cur.next;
            ListNode temp2=cur.next.next.next;
            cur.next=cur.next.next;
            temp1.next.next=temp1;
            temp1.next=temp2;
            cur=temp1;
            
        }
        return dummy.next;
    }

此外还可以用递归,递归更像是直白的思路 

public ListNode swapPairs(ListNode head) {
        // 递归版本
        if(head==null || head.next==null){
            return head;
        }
        ListNode next=head.next;
        ListNode newNode=swapPairs(next.next);
        next.next=head;
        head.next=newNode;
        return next;
    }

 测试用例:

1.输入偶数节点个数的链表

2.输入奇数节点个数的链表

3.输入只有一个节点的链表

4.输入空链表

 ✿LeetCode19.删除链表的倒数第N个节点❀

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

 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

【链表part02】| 24.两两交换链表中的节点、19.删除链表的倒数第N个节点、02.07.链表相交、142.环形链表_第2张图片

对于链表题目,不得不考虑头结点,如果要删除的元素是头结点该怎么操作呢?答案就是设计一个虚拟头结点dummy,这样头结点就可以看成一个普通的节点进行操作了,这道题的思路就是让fast先走n+1步,然后fast和slow一起走,fast=null的时候,slow正好是要删除节点的前一个节点,具体代码如下:

public ListNode removeNthFromEnd(ListNode head, int n) {
        // 1 <= n <= sz
        // 1 <= sz <= 30  
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode fast=dummy;
        // fast先走n+1步
        for(int i=0;i

测试用例:

1.删除链表中间的一个节点

2.删除链表末尾的一个节点

3.删除头结点

4.n<1或n>size(题目没有这类用例)

5.链表为空(题目没有这类用例)

✿LeetCode面试题 02.07. 链表相交❀

链接:02.07.链表相交

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

【链表part02】| 24.两两交换链表中的节点、19.删除链表的倒数第N个节点、02.07.链表相交、142.环形链表_第3张图片

快慢指针可以解决链表中的很多问题,此题就是一个典型的例子,先计算出两个链表的长度差len,长的链表先走 len步,然后两个链表一起走,相等的时候即相交,代码如下:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null || headB==null){
            return null;
        }
        int lenA=0;
        int lenB=0;
        ListNode indexA=headA;
        ListNode indexB=headB;
        while(indexA!=null){
            lenA++;
            indexA=indexA.next;
        }
        while(indexB!=null){
            lenB++;
            indexB=indexB.next;
        }
        if(lenB>lenA){
            ListNode temp=headA;
            headA=headB;
            headB=temp;
        }
        indexA=headA;
        indexB=headB;
        int len=Math.abs(lenA-lenB);
        while(len>0){
            indexA=indexA.next;
            len--;
        }
        while(indexA!=null && indexB!=null){
            if(indexA==indexB){
                return indexA;
            }
            indexA=indexA.next;
            indexB=indexB.next;
        }
        return null;
    }

 测试用例:

  1. 输入两个相交的链表且两个链表的长度不同
  2. 输入两个不想交的链表
  3. 输入的两个链表其中有一个是空链表
  4. 输入的两个都是空链表
  5. 输入两个相等的链表(从头结点就相交)
  6. 输入的两个链表最后一个节点才相交

✿LeetCode142.环形链表||❀ 

链接:142.环形链表||

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表

【链表part02】| 24.两两交换链表中的节点、19.删除链表的倒数第N个节点、02.07.链表相交、142.环形链表_第4张图片

 这道题首先要判断是否有环,定义一个快慢指针,快指针每次走两步,慢指针每次走一步,如果两个指针相遇的话就代表有环,如果快指针指向null了就代表无环(环形链表拥有不可能指向空),如果有环再计算入环的第一个节点的下标,计算过程如下:

快指针走了x+y+n(y+z),慢指针走了x+y,又有快指针走的步数是慢指针的两倍,所以

x+y+n(y+z)=2(x+y)  ->  x+y=n(y+z)

我们要求的是x: x=n(y+z)-y=(n-1)(y+z)-z

当n=1的时候 x=z

所以当快慢指针相遇时,一个指针从相遇点出发,一个指针从头结点出发,两指针相遇的节点即为入环的第一个节点,代码如下:

 【链表part02】| 24.两两交换链表中的节点、19.删除链表的倒数第N个节点、02.07.链表相交、142.环形链表_第5张图片

public ListNode detectCycle(ListNode head) {
        if(head==null || head.next==null){
            return null;
        }
        ListNode fast=head;
        ListNode slow=head;
        // 看是否有环
        while(fast!=null && fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            // 有环
            if(fast==slow){
               slow=head;
               while(fast!=null){
                   if(slow==fast){
                       return slow;
                   }
                   slow=slow.next;
                   fast=fast.next;
                   
               }
            }
        }
        return null;
    }

 测试用例:

  1. 输入一个有环的链表
  2. 输入一个无环的链表
  3. 输入一个只有一个节点的链表
  4. 输入一个空链表

你可能感兴趣的:(链表,数据结构)