(Leetcode)链表的slow,fast指针使用

141. Linked List Cycle

Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?

Code-Java

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow, fast;
        slow = fast = head;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(slow==fast) return true;
        }
        return false;
    }
}

142. Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Note: Do not modify the linked list.
Follow up:
Can you solve it without using extra space?

Code-Java

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head, slow = head;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast==slow){
                while(slow!=head){//fast和slow meet的node到环开始的node的距离s1,等于head到环开始的node的距离s2
                    head = head.next;
                    slow = slow.next;
                }
                return slow;
            }
        }
        return null;
    }
}

为什么 fast和slow meet的node到环开始的node的距离s1,等于head到环开始的node的距离s2?

Definitions:

cycle : length of the cycle, if exists.
start_dis : the distance from the head to Node_begin (the begin node of cycle).
meet_dis : the distance from Node_begin to the Node_meet(where slow and fast meet).
remaining_meet_dis : the distance from the Node_meet to Node_begin
we can see, meet_dis + remaining_meet_dis = cycle

Distance(slow) = start_dis + meet_dis + k1·cycle
Distance(fast) = start_dis + meet_dis + k2·cycle

 Distance(slow)*2 = Distance(fast)
=> start_dis + meet_dis = (k2-2k1)·cycle = k·cycle
=> start_dis = k·cycle - meet_dis = remaining_meet_dis

therefore, s1 = s2

143. Recorder List

Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You must do this in-place without altering the nodes' values.

For example,
Given {1,2,3,4}, reorder it to {1,4,2,3}.

Solution

1。利用slow、fast指针找到list的middle——O(n)
2。将middle之后的node翻转——O(n/2)
3。讲后面一半list插入前一半——O(n/2)
整个过程时间复杂度O(n),空间复杂度O(1)

Code

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public void reorderList(ListNode head) {
        if(head==null || head.next==null || head.next.next==null) return;
        ListNode slow = head, fast = head;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
        }
        ListNode middle = slow;
        ListNode pre  = slow.next;

        //reverse the half listnode after the middle
        while(pre.next!=null){
            ListNode cur = pre.next;
            pre.next = cur.next;
            cur.next = middle.next;
            middle.next = cur;
        }

        pre = head;
        //insert the reversed half into pre half
        while(middle.next!=null){
            ListNode cur = middle.next;
            middle.next = cur.next;
            cur.next = pre.next;
            pre.next = cur;
            pre = cur.next;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值