代码随想录算法训练营第4天 | 24.两两交换链表中的节点、707.设计链表、160.链表相交、142.环形链表

目录

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

代码实现

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

代码实现

160.链表相交

代码实现

142.环形链表

代码实现


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

题目链接:两两交换链表中的节点

代码实现

当前cur要在交换的两个之前才能实现操作

注意画个图看哪些链子断了,就需要拿中间变量去收集断了的值,断了是指没有和dummyhead这条链相连的节点。

public ListNode swapPairs(ListNode head) {
        ListNode dummyhead=new ListNode();
        dummyhead.next=head;//定义一个虚拟头节点
        ListNode cur=dummyhead;
        //cur.next.next==null就不遍历了
        //先判断cur.next!=null再判断cur.next.next!=null
        //因为当cur.next=null时还没判断,已经就开始判断cur.next.next就会出现空指针异常
        //可以这样判断是因为是操作交换的两个数的前一位
        while (cur.next!=null&&cur.next.next!=null){
            ListNode tmp=new ListNode();
            ListNode tmp3=new ListNode();
            //要保存节点1和节点3,因为节点2断了1和3的节点
            tmp=cur.next;
            tmp3=cur.next.next.next;

            cur.next=cur.next.next;//现在的cur.next已经指向了第二个节点(没变之前的第二个)
            cur.next.next=tmp;
            tmp.next=tmp3;
            //tmp.next=tmp.next.next;这个位置已经找不到节点3了,画图理解
            cur=cur.next.next;//cur指向变了的第二个,这里的cur才开始改变指向
                              //上面部分只是改变cur.next等的指向

        }
        return dummyhead.next;//不能return head,因为dummyhead.next会变,而head不会变,head.next变就不是head了
                              //dummyhead.next改变为头节点

    }

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

题目链接:删除链表倒数第N个节点

代码实现

使用双指针,当fast比slow多走n步时,当fast指向null时slow指向倒数第n个

由于删除增加操作要在删除节点位置前一个操作,所以fast应比slow多走n+1步,当fast指向null时slow指向倒数第n+1.

 public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummyhead=new ListNode();
        dummyhead.next=head;

        ListNode slow=new ListNode();
        ListNode fast=new ListNode();
        fast=dummyhead;
        slow=dummyhead;
        n++;
        //只要fast比slow快n+1就行了,此时slow指向倒数第n个的前一个
        while (n>0){
            fast=fast.next;
            n--;
        }
        while (fast!=null){
            fast=fast.next;
            slow=slow.next;
        }
        slow.next=slow.next.next;//进行删除
        return dummyhead.next;

    }

160.链表相交

题目链接:链表相交

代码实现
//先移到长链表实现同步移到
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        ListNode curA=headA;
        ListNode curB=headB;
        int lenA=0;
        int lenB=0;
        //求链表A的长度
        while (curA!=null){
            lenA++;
            curA=curA.next;
        }
        //求链表B的长度
        while (curB!=null){
            lenB++;
            curB=curB.next;
        }
        curA=headA;
        curB=headB;
        //让curA成为最长链表的头,其长度为lenA
        if (lenB>lenA){
            //交换lenA,lenB
            int tmplen=lenA;
            lenA=lenB;
            lenB=tmplen;
            //交换curA,curB
            ListNode tmpnode=curA;
            curA=curB;
            curB=tmpnode;
        }
        //求长度
        int gap=lenA-lenB;
        //让curA指向位置与curB指向B的末尾对其
        while (gap>0){
            curA=curA.next;
            gap--;
        }
        //遍历curA和curB,遇到相同的则直接返回
        while (curA!=null){
            if (curA==curB){
                return curA;
            }
            curA=curA.next;
            curB=curB.next;
        }
        return null;

    }

142.环形链表

题目链接:环形链表

代码实现

如何判断一个链表是否有环,用一个快指针一个慢指针,如果他们相遇就说明有环。

快指针每次走两步,慢指针每次走一步,相当于快指针每次以一个节点的速度靠近慢指针,所以成环时快慢指针一定相遇。

    public ListNode detectCycle(ListNode head) {
        ListNode slow=head;
        ListNode fast=head;
        while (fast!=null&&fast.next!=null){
            //fast和slow的指向改变了
            fast=fast.next.next;
            slow=slow.next;
            if (slow==fast){//有环
                ListNode index1=fast;
                ListNode index2=head;
                //两个指针从头节点和相遇节点,各走一步,直到相遇,相遇点及为环节点入口
                while (index1!=index2){
                    index1=index1.next;
                    index2=index2.next;
                }
                return index1;
            }
        }
        return null;

    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值