码不停题:LeetCode 75-Day4【链表】

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解析

解题的思路:首先需要找到中间节点的位置,那就必须获取到节点的长度

  • 如果节点长度为偶数,则从中间节点位置开始遍历
  • 如果节点长度为奇数,则从中间节点位置+ 1开始遍历

📝代码实现

class Solution {
    public ListNode middleNode(ListNode head) {
        int length = getNodeLength(head);
        //长度为偶数
        if(length % 2 == 0){
            //遍历节点,从中间节点截取即可
            for(int i = length / 2; i < length; i++){
                head = head.next;
            }
        }
        //若为奇数,则 length / 2 + 1
        else
        {
            for(int i = length / 2 + 1; i < length; i++){
                head = head.next;
            }
        }
        return head;
    }
    /*
    * 遍历节点 获取长度
     */
    public int getNodeLength(ListNode head){
        int length = 0;
        while(null != head){
            length++;
            head = head.next;
        }
        return length;
    }
}

📈复杂度分析

时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表1.5次。

空间复杂度:O(1)

💡思路2解析

解题的思路:首先需要找到中间节点的位置,另一种思路就是快慢指针,快指针每次都比慢指针多遍历一次,当快指针遍历结束时,此时慢指针刚好到中间节点

📝代码实现

class Solution {
    public ListNode middleNode(ListNode head) {
        //初始化快慢指针,都从头结点开始
        ListNode fast = head; ListNode slow = head;
        //当快指针不为空,且下一节点不为空时
        while(null != fast && null != fast.next){
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
}

📈复杂度分析

时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表1次。

空间复杂度:O(1)

142. 环形链表 II

❓题目描述

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

👉题目示例

示例 1:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PYTcL2Nc-1657376558071)(🧡 LeetCodeImages/circularlinkedlist.png)]

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AaOcNuDp-1657376558073)(🧡 LeetCodeImages/circularlinkedlist_test2-16573751940283.png)]

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wb72pC9O-1657376558074)(🧡 LeetCodeImages/circularlinkedlist_test3-16573752092085.png)]

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

💡题目解析

💡思路解析

因是环行链表,每次遍历的时候记录遍历的节点,如若遇到重复的节点,则说明该节点是环形节点

📝代码实现

public class Solution {
    public ListNode detectCycle(ListNode head) {
       ListNode pos = head;
        //set集合存储节点
        Set<ListNode> visited = new HashSet<ListNode>();
        while (pos != null) {
            //如果包含,则说明该节点是环形节点
            if (visited.contains(pos)) {
                return pos;
            } else {
                visited.add(pos);
            }
            //重新赋值
            pos = pos.next;
        }
        return null;
    }
}

📈复杂度分析

时间复杂度:O(N),其中 N 为链表中节点的数目。我们恰好需要访问链表中的每一个节点。

空间复杂度:O(N),其中 N为链表中节点的数目。我们需要将链表中的每个节点都保存在哈希表当中。

posted on 2022-09-06 09:01  小熊学Java  阅读(23)  评论(0)    收藏  举报