力扣24、19、160、142打卡第四天

今天还可以,除了环形链表那里,其他都很顺。

第24题:

同样,链表这个东西最后让返回头指针最好的办法就是做一个假的头指针。本题用了三个指针一个保存头指针,第二个遍历链表。第三个防止断链做暂时的存放。思路比较简单代码如下:

public ListNode swapPairs(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode pre = new ListNode(0);
        pre.next = head.next;
        ListNode cur = head;
        ListNode temp = cur;
        while (cur.next != null) {
            if (temp.next == null) {
                return pre.next;
            }
            cur.next = temp.next;
            cur = temp;
            temp = temp.next;
            cur.next = temp.next;
            temp.next = cur;
            temp = cur.next;

        }
        return pre.next;
    }

19题做过了两种方法,快慢指针和循环两遍,都不是很难这里用的是循环两遍的方法:

public ListNode removeNthFromEnd(ListNode head, int n) {
        if(head.next==null){return null;}
        int count = 0;
        ListNode tmp = head;
        while (tmp.next!=null){
            tmp = tmp.next;
            count++;
        }
        if (++count==n){
            tmp = head.next;
            return tmp;
        }
        tmp = head;
        for (int i=0;i<count-n-1;i++){
            tmp = tmp.next;
        }
        tmp.next = tmp.next.next;
        return head;
    }

160题这个题很有意思借用卡尔老师的一张图:

 

 

看清题很重要只要找到两个链表的长度差,然后对齐向后一一对比即可代码如下

 public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA = headA;
        ListNode curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != null) { // 求链表A的长度
            lenA++;
            curA = curA.next;
        }
        while (curB != null) { // 求链表B的长度
            lenB++;
            curB = curB.next;
        }
        curA = headA;
        curB = headB;
        // 让curA为最长链表的头,lenA为其长度
        if (lenB > lenA) {
            //1. swap (lenA, lenB);
            int tmpLen = lenA;
            lenA = lenB;
            lenB = tmpLen;
            //2. swap (curA, curB);
            ListNode tmpNode = curA;
            curA = curB;
            curB = tmpNode;
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap-- > 0) {
            curA = curA.next;
        }
        // 遍历curA 和 curB,遇到相同则直接返回
        while (curA != null) {
            if (curA == curB) {
                return curA;
            }
            curA = curA.next;
            curB = curB.next;
        }
        return null;
    }

142题,重中之重,难上加难

这里开始讲解头指针H然后设置快慢指针,快指针的速度为2慢指针的速度为1.由此可以保证两个事情,第一在相对速度为1的情况下如果存在环快指针一定不会跳过慢指针。2.快指针一定会在慢指针进圈的第一圈就追上。

然后我们设从头指针到入口的距离为x,从入口到追上的点的距离为y,从meet点到入口的距离为z。得到等式:

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

等式左边是慢指针的路程吧,右边是快指针的,n代表快指针在满指针进入圈之前转了多少圈

然后化简得到

x = (n-1)(z+y)+z

由此得到结论x与z有直接关系,也就是当两个指针同时从头指针以及meet点出发以1的速度向前走一定会在入口处相遇。

以下为代码

public ListNode detectCycle(ListNode head) {
        if(head==null||head.next==null){return null;}
        ListNode fast = head;
        ListNode slow = head;
        // while(fast!=slow&&fast.next!=null){
        //     fast = fast.next.next;
        //     slow = slow.next;
        // }
        // if(fast==null){return null;}
        // ListNode ptr = head;
        // while (ptr != slow) {
        //     ptr = ptr.next;
        //     slow = slow.next;
        // }
        // return ptr;
         while (fast != null) {
            slow = slow.next;
            if (fast.next != null) {
                fast = fast.next.next;
            } else {
                return null;
            }
            if (fast == slow) {
                ListNode ptr = head;
                while (ptr != slow) {
                    ptr = ptr.next;
                    slow = slow.next;
                }
                return ptr;
            }
        }
        return null;

上边还写错了一点

有大佬可以帮我看看哪里错了吗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值