算法训练04交换链表节点+删除链表倒数的节点+链表相交+环形链表

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

示例:

输入:head = [1,2,3,4]
输出:[2,1,4,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) {

        //1.利用虚拟头节点+临时存储节点

        ListNode dummy=new ListNode(){};

        dummy.next=head;

        ListNode cur =dummy;

        while(cur.next!=null&&cur.next.next!=null){//考虑循环停止条件

            ListNode temp1=cur.next;

            ListNode temp2 = cur.next.next;

            cur.next=temp2; //cur指向2

            temp1.next=temp2.next;//1指向3

            temp2.next=temp1;//2指向1

            cur=temp1;//cur移动2位

        }

        return dummy.next;

    }

}

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

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

错误:

修正:

核心:第一考虑极端情况 删除的是头节点和尾节-虚拟头节点,//采用办法为求size+遍历

方法二 快慢指针-办法是两个指针相差n个然后一起遍历直到fast到最后一个,此时slow指针就是要处理的值前一个

答案:

/**

 * 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 removeNthFromEnd(ListNode head, int n) {

        //1.考虑极端情况 删除的是头节点和尾节点,

        //采用办法为求size+遍历

        ListNode dummy= new ListNode(){};

        dummy.next=head;

        ListNode cur=dummy;

        int size=0;

        while(cur.next!=null){

            cur=cur.next;

            size++;

        }

        cur=dummy;

        for(int i=0; i<size-n;i++){

             cur=cur.next;

        }

        ListNode temp=cur.next.next;

        cur.next=temp;

        return dummy.next;

    }

    //方法二 快慢指针-办法是两个指针相差n个然后一起遍历直到fast到最后一个,此时slow指针就是要处理的值前一个

}

题目3: 

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

图示两个链表在节点 c1 开始相交

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

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

输入headA headB 输出c1

错误:

修正:

核心:

/*1.找规律 快慢指针,fast比slow快size差步

            2.找出停止条件 快慢指针指向的是同一个

            3.找出极端情况

                --不相交 从来没有相等输出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) {

        /*1.找规律 快慢指针,fast比slow快size差步

            2.找出停止条件 快慢指针指向的是同一个

            3.找出极端情况

                --不相交 从来没有相等输出null

                --完全相交 正常输出 */

        if(headA==null||headB==null){

            return null;

        }//考虑空值极端情况

        int sizeA=0;

        ListNode curA=headA;

        while(curA.next!=null){

            curA=curA.next;

            sizeA++;

        }

        int sizeB=0;

        ListNode curB=headB;

   

        while(curB.next!=null){

            curB=curB.next;

            sizeB++;

        }

        //!让curA成为最长链表的头

        curA=sizeA>=sizeB?headA:headB;

        curB=sizeA<sizeB?headA:headB;

        int sizeCha=(sizeA-sizeB)>=0?(sizeA-sizeB):(sizeB-sizeA);

        //长链表先走sizaCha

        for(int i=0; i<sizeCha;i++){

            curA=curA.next;

        }

        while(curA!=curB){

              if(curA.next==null||curB.next==null){

                return null;

              }

            curA=curA.next;

            curB=curB.next;

        }

        return curA;

    }

}

 题目4:

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

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

不允许修改 链表。

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

错误:

修正:

核心: 一个指针从头节点走,一个从相遇位置走,每次一步,第一个相遇的就是入口节点(因为刚好差环这么多步)

答案:

public class Solution {

    public ListNode detectCycle(ListNode head) {

        //1.找规律--快慢指针

            //快慢指针步数 差环的长度/环长度的倍数 时候一定会指向同一个节点

            //环的长度从1-2-3-~

            //每次差1或者2或者3或者````->快指针走2步,慢指针走1步

        //2.找停止条件

            //指向同一个节点,停止输出

        //3.找极端情况

            //空值

            //没有环

        if(head==null||head.next==null){

            return null;

        }

        ListNode curFast=head;

        ListNode curSlow=head;

        curFast=curFast.next.next;

        curSlow=curSlow.next;

        while(curFast!=curSlow){

            if(curFast==null||curFast.next==null||curSlow==null){

                return null;

            }

            curFast=curFast.next.next;

            curSlow=curSlow.next;

        }

        //一个指针从头节点走,一个从相遇位置走,每次一步,第一个相遇的就是入口节点(因为刚好差环这么多步)

         curSlow=head;

        while(curFast!=curSlow){

            curSlow=curSlow.next;

            curFast=curFast.next;  

        }

        return curSlow;

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值