查看: 1063| 回复: 7
跳转到指定楼层
上一主题 下一主题
收起左侧

[Leetcode] Leetcode笔记 #141. Linked List Cycle

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
本帖最后由 liuzz10 于 2020-8-26 14:03 编辑

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

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Author's note
I’m not sure how pos is related to the problem itself but it teaches us how to represent a cycle in future coding practice.

Idea 1: Hash Table
The idea is very clear. We check every node and see we have seen this node before, if not, save into the hash table and check the next node.

HashSet vs. HashMap
Why do we choose a HashSet instead of a HashMap?
  • HashSet is a set, e.g. {1, 2, 3, 4, 5},
  • HashMap is a key -> value pair map, e.g. {a -> 1, b -> 2, c -> 2, d -> 1}

Since we only need to save one node (actually it’s the address of the node) instead of a key-value pair, we’d like to choose a HashSet instead of a HashMap.

HashSet
There are 3 commands that we should know to solve this problem.
  • Create: Set<ListNode> seen = new HashSet<ListNode>();
  • Check if X is contained in a HashSet: seen.contains(X) // true or false
  • Add X to a HashSet: seen.add(X)



Code

  1. // Hash Table
  2. public class Solution {
  3.     public boolean hasCycle(ListNode head) {
  4.         // Create a hashtable
  5.         Set<ListNode> seen = new HashSet<ListNode>();
  6.         
  7.         // We check every node and see we have seen this node before,
  8.         // if not, save into the hash table and check the next node.
  9.         while (head != null) {
  10.             if (seen.contains(head)) return true;
  11.             else seen.add(head);
  12.             head = head.next;
  13.         }
  14.         return false;
  15.     }
  16. }
复制代码



Idea 2: 2 pointers
We can use 2 pointers with different speed and check if they meet. So we need to design their speed careful so that they don’t miss each other, like this:
  • Creating a pointer slow who walks 1 step each time
  • Creating a pointer fast who walks 2 steps each time.

In this way they will finally meet. “Leetcode - solutions” explains this part very well.


Code

  1. // 2 pointers
  2. public class Solution {
  3.     public boolean hasCycle(ListNode head) {
  4.         // Since we're using the value of head and head.next to initialize pointers,
  5.         // we need to make sure that they are not null.
  6.         if (head == null || head.next == null) return false;
  7.         
  8.         // Set up 2 pointers
  9.         ListNode slow = head;
  10.         ListNode fast = head.next;
  11.         while (slow != fast) {
  12.             if (fast == null || slow == null) return false;
  13.             fast = fast.next.next;  // fast.next.next is different with head.next.next in #206(recursive) since here fast.next.next doesn't change it's value while head.next.next in #206(recursive) is assigned to a new value so that it's pointing back.
  14.             slow = slow.next;
  15.         }
  16.         
  17.         // Only return true when 2 pointers are the same
  18.         return true;
  19.     }
  20. }
复制代码


上一篇:求大家帮忙看一下SAP今年ng的一道api design的题
下一篇:请问LC有没有类似的题?
全局:
方法一里面第10行和11行可以写得更compact一些,
  1. if (!seen.add(head)) return true;
复制代码
回复

使用道具 举报

🔗
ahbbzong 2020-8-27 08:02:27 | 只看该作者
全局:
快慢指针是个特别好的办法,linked list里面很多题都可以用它来实现。 除了判断circle,快慢指针可以帮助我们找到linked list的中点,对处理回文,merge linkedin list方面都有许多帮助
回复

使用道具 举报

🔗
 楼主| liuzz10 2020-8-27 08:02:52 | 只看该作者
全局:
不知道小帅 发表于 2020-8-26 15:54
方法一里面第10行和11行可以写得更compact一些,
[mw_shl_code=java,true]if (!seen.add(head)) return tr ...

查到了说:
Return Value: The function returns True if the element is not present in the HashSet otherwise False if the element is already present in the HashSet.
原来.add()还有return value!
回复

使用道具 举报

🔗
 楼主| liuzz10 2020-8-27 08:06:12 | 只看该作者
全局:
ahbbzong 发表于 2020-8-26 16:02
快慢指针是个特别好的办法,linked list里面很多题都可以用它来实现。 除了判断circle,快慢指针可以帮助我 ...

不知道是不是我刷题不够多,感觉快慢指针在array里出现的比较少,一到了linked list就有一些linked list-specific的方法出现了,除了快慢指针之外,还有recursion
回复

使用道具 举报

🔗
ahbbzong 2020-8-27 08:09:26 | 只看该作者
全局:
本帖最后由 ahbbzong 于 2020-8-27 08:11 编辑
liuzz10 发表于 2020-8-27 08:06
不知道是不是我刷题不够多,感觉快慢指针在array里出现的比较少,一到了linked list就有一些linked list- ...
其实原因很简单,array 不需要快慢指针这种麻烦办法,array 可以直接access 到任意一个index。一般在linked list里面出现的比较多,这是linked list 里面的一个典型用法。我觉得linked list 和 tree那个模块一样,都自己的套路,需要专项练习
回复

使用道具 举报

🔗
 楼主| liuzz10 2020-8-27 08:12:31 | 只看该作者
全局:
ahbbzong 发表于 2020-8-26 16:09
其实原因很简单,array 不需要快慢指针这种麻烦办法,array 可以直接access 到任意一个index。一般在linked ...

是,刷过一些array的题之后刷linked list感觉落差很大,经验基本不能复用
回复

使用道具 举报

🔗
ahbbzong 2020-8-27 08:14:18 | 只看该作者
全局:
liuzz10 发表于 2020-8-27 08:12
是,刷过一些array的题之后刷linked list感觉落差很大,经验基本不能复用

我感觉一共就10-20种套路。熟练就好了,大部分题做不出感觉不是不会套路,而是没看出来套路哈哈哈
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表