本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接
环形链表(141)
题目描述
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true。 否则,返回 false 。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
进阶
你能用内存解决此问题吗?
注意
- 链表中节点的数目范围是
[0, 104] -105 <= Node.val <= 105pos为-1或者链表中的一个 有效索引 。
思路分析
如果链表有环,分别用一个快指针,每次遍历两个,一个慢指针,每次遍历一个,如果存在环,那么这两个指针最终会相交的。
代码展示
时间复杂度是,空间复杂度是。
public static boolean hasCycle(ListNode head) {
ListNode quick = head;
ListNode slow = head;
while (quick != null && quick.next != null){
quick = quick.next.next;
slow = slow.next;
if (quick == slow){
return true;
}
}
return false;
}
链表的中间节点(876)
题目描述
给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
提示
- 给定链表的结点数介于
1和100之间。
思路分析
分别用一个快指针,每次遍历两个,一个慢指针,每次遍历一个,快指针达到末尾,慢指针就达到中点了。
代码展示
时间复杂度是,空间复杂度是。
public static ListNode middleNode(ListNode head) { //1,2,3,4,5,6
//双指针解法
if (head == null) {
return null;
}
ListNode quick = head;
ListNode slow = head;
while (quick != null && quick.next != null) {
quick = quick.next.next;
slow = slow.next;
}
return slow;
//单指针解法
//放到数组中也可以
}
总结
双指针解法在链表中还是挺常用的,需要好好的掌握。