五道经典链表题

题目的牛客网链接:
https://www.nowcoder.com/ta/leetcode?tagQuery=%E9%93%BE%E8%A1%A8&page=1

基本链表类定义

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */

单链表反转 Reverse Linked List

public static ListNode reverseBetween(ListNode head, int m, int n) {
    // 设置哨兵
    ListNode dump = new ListNode(0);
    dump.next = head;
    ListNode pre = dump;
    ListNode start = head;
    // 循环至方向的起始点
    for (int i = 1; i < m; i++) {
        pre = start;
        start = start.next;
    }
    // 将链表从m到n的节点反向
    for (int i = 0; i < n-m; i++) {
        ListNode temp = start.next;
        start.next = temp.next;
        temp.next = pre.next;
        pre.next = temp;
    }
    return dump.next;
}

链表中环的检测 Linked List Cycle

public ListNode detectCycle(ListNode head) {
    if (head == null) {
        return null;
    }
    // 设置快慢指针,每次循环,慢指针移动一步,快指针移动两步
    ListNode slow1 = head;
    ListNode fast = head;
    while (fast.next != null && fast.next.next != null) {
        fast = fast.next.next;
        slow1 = slow1.next;
        // 若链表中存在环,则快慢指针会相遇
        if (slow1 == fast) {
            // 再次循环遍历到环的起始点
            ListNode slow2 = head;
            while (slow2 != fast) {
                slow2 = slow2.next;
                fast = fast.next;
            }
            return slow2;
        }
    }
    return null;
}

两个有序的链表合并 Merge Two Sorted Lists

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    ListNode dummy = new ListNode(-1);
    ListNode cur = dummy;
    ListNode node1 = l1;
    ListNode node2 = l2;
    // 题目设定是两个链表均为有序链表
    // 因此直接遍历,比较大小,并合并为一个链表
    while (node1 != null && node2 != null) {
        if (node1.val < node2.val) {
            cur.next = node1;
            node1 = node1.next;
        } else {
            cur.next = node2;
            node2 = node2.next;
        }
        cur = cur.next;
    }
    // 拼接剩余链表
    if (node1 == null) {
        cur.next = node2;
    }
    if (node2 == null) {
        cur.next = node1;
    }
    return dummy.next;
}

删除链表倒数第 n 个结点 Remove Nth Node From End of List

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode dummy = new ListNode(-1);
    dummy.next = head;
    ListNode slow = dummy;
    ListNode fast = dummy;
    // 用对称性,先找到开头的第n个节点
    while (fast != null && n >= 0) {
        fast = fast.next;
        n--;
    }
    // 两个指针同步移动,当快指针到达末尾时,慢指针到达倒数第n个节点
    while (fast != null) {
        fast = fast.next;
        slow = slow.next;
    }
    slow.next = slow.next.next;
    return dummy.next;
}

求链表的中间结点 Middle of the Linked List

  • 牛客网中没有,LeetCode编号876
public ListNode middleNode(ListNode head) {
    // 设置快慢两个指针
    // 慢指针每次移动一步
    // 快指针每次移动两步
    ListNode slow = head;
    ListNode fast = head;
    while (fast.next != null && fast.next.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    // 链表个数为奇数和偶数的处理
    if (fast.next == null) {
        return slow;
    } else {
        return slow.next;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值