有关快慢指针或者双指针的算法

1、可以判断单向链表中是或否含有环。【快慢指针】

思路:慢指针slow指向头结点,快指针fast指向头结点的next结点,当fast != null && fast.next != null的时候,slow每次移动一步,fast每次移动两步,如果fast == slow,即快慢指针相遇,说明链表中含有环。

   public boolean hasCycle(ListNode head) {

        //使用快慢指针的思想解决问题(追击问题)

        if (head == null) return false;

        ListNode slow = head; // 慢指针
        ListNode fast = head.next; // 快指针

        // 在fast不等于空的前提下,一直进行到 fast 追赶到 slow
        while (fast != null && fast.next != null){

            if (slow == fast) return true;

            slow = slow.next; // 慢指针每次前进一步
            fast = fast.next.next; // 快指针每次前进两步

        }

        return false;

    }

该思路也可以找到环的入口:在上述的思路下,让a指针指向head,b指向slow.next,然后同时后移,当a和b相遇的时候,a指向环的入口。

public ListNode cycleEntrance(ListNode head) {

        ListNode a = head;
        ListNode slow = head;
        ListNode fast = head.next;

        while (fast != null && fast.next != null){

            if (slow == fast) break;

            slow = slow.next;
            fast = fast.next.next;

        }

        ListNode b = slow.next;
        while (a != b){
            a = a.next;
            b = b.next;
        }

        return a;

    }

2、可以找到单向链表中的倒数第k个结点。【快慢指针】

思路:链表的长度为 len,需要找到倒数第k【从1开始计数】个节点(即找到正数第len-k【从0开始计数】个节点),让fast和slow都指向头结点,首先先让fast移动k步,然后slow和fast同时每次移动一步,当fast==null的时候,

此时slow正好指向第len-k个节点,即倒数第k个节点。

    public int kthToLast2(ListNode head, int k) {

        ListNode fast = head;
        ListNode slow = head;

        while (k > 0){
            k--;
            fast = fast.next;
        }

        while (fast != null){
            slow = slow.next;
            fast = fast.next;
        }

        return slow.val;

    }

3、可以寻找到单向链表的中间结点。【快慢指针】

思路:慢指针slow指向头结点,快指针fast也指向头结点,当fast != null && fast.next != null的时候,slow每次移动一步,fast每次移动两步,最终slow指向中间结点。

    public ListNode middleNode(ListNode head) {

        ListNode slow = head;
        ListNode fast = head;

        while (fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;

    }

4、可以让两个长度不同的链表同时到达尾结点。【双指针】

思路:链表headA和headB,la,lb分别指向头结点,然后分别后移,当某一个为null的时候,让其指向另外一个链表的头结点,再一步后移,这样,两个指针就会同时到达另外一个链表的尾结点。(因为两个链表的总长是一定的)

这个思路可以解决两个链表是否相交的问题,即时候含有相同的结点,不仅针对结点的val。

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        ListNode la = headA;
        ListNode lb = headB;

        while (la != lb){

            la = (la == null) ? headB : la.next;
            lb = (lb == null) ? headA : lb.next;
        }

        return la;

    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值