[LeetCode][环型链表]linked-list-cycle(java) 链表中环的入口结点 判断是否是环形链表

1.题:

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?

解析:一开始拿到这个题目我竟然没有看懂;自己的思路可能判断环形链表,需要前后指针,(思维固化)直接看了别人的思路,发现判断环形链表可以定义两个指针:快指针,慢指针,从head开始,让快指针一次走两步,慢指针一次走一步,如果是环形的链表,则快指针和慢指针一定会相遇,为什么呢,类似跑道里的两个人跑步,跑的快的一定会在第一圈以后多跑追上跑的慢的;即使在某一圈快指针跳过了慢指针,但是总有一圈他们会相遇;

思路:

1)定义两个指针指向head;

2)while判定条件,如果fast碰到null即停止;

3)让结点走,判断两个指针是否相等;

/**
 * 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 fast = head;
        ListNode slow = head;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                return true;
            }
        }
        return false;
    }
}

备注:

面试的时候 一定要表现自己在思考这个问题,层层递进,不要一下子说出快慢指针的解决方案,一说面试官就知道你刷过题;

分两种情况讨论:第一种我能想到的是使用一个标志位,如果这个点被访问过,那就是添加一个flag为true,每次next下一个指针的时候,如果有flag显示true,说明链表有环;第二种是像刷题网站中那种定死的数据结构,然后不能开辟别的空间,只能在node上面处理的话,那就是快慢指针了;

 

2.linked-list-cycle-ii

Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull.

Follow up:
Can you solve it without using extra space?

 这个题目的思路跟上面的也很像;判断环形链表的第一个点;如果无环,返回null;

这个是在题一的基础上添加,题一判断有环的地方添加,判断环形链表的起始点,

参考:假设快慢指针在环上第k个节点相遇,而环的起点是链表第m个节点,环的总长度是n。此时慢指针再走n-k步就回到了环的开头,而此时快指针已经走了m+k步。如果我们这时候将快指针放回起点,并让它也一次走1步,这样当两个节点再次相遇时,相遇点就是环的起点。

 * 思路:

 * 1)首先判断是否有环,有环时,返回相遇的节点,无环,返回null

 * 2)有环的情况下, 求链表的入环节点

 *   fast再次从头出发,每次走一步,

 *   slow从相遇点出发,每次走一步,

 *   再次相遇即为环入口点。

 

/**
 * 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;
        ListNode slow = head;
        ListNode p = head;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast==slow){
                slow = head;
                while(slow!=fast){
                    slow = slow.next;
                    fast = fast.next;
                }
                return slow;
            }
        }
        return null;
    }
}

还可以有一种 直接定义一个数据结构hashSet 然后add node 如果已经存在的话 就返回true 否则返回null

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
import java.util.*;
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
       /* ListNode fast = pHead;
        ListNode slow = pHead;
        ListNode p = pHead;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast==slow){
                slow = pHead;
                while(slow!=fast){
                    slow = slow.next;
                    fast = fast.next;
                }
                return slow;
            }
        }
        return null;*/
       
        HashSet<ListNode> set = new HashSet<ListNode>();
        while (pHead != null) {
            //如果已存在则调用Object对象的equals方法判断是否返回true,如果为true则说明元素已经存在,如为false则插入元素。
            if (!set.add(pHead)) {
                return pHead;
            }
            pHead = pHead.next;
        }
        return null;
    }
}

参考:https://segmentfault.com/a/1190000003718848

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值