找回密码
 立即注册
首页 业界区 业界 hot100之链表上

hot100之链表上

闻成 2025-6-14 12:40:00
相交链表(160)

先看代码
  1. public class Solution {
  2.     public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  3.         ListNode p = headA;
  4.         ListNode q = headB;
  5.         while (p != q){
  6.             p = p != null ? p.next : headB;
  7.             q = q != null ? q.next : headA;
  8.         }
  9.         return p;
  10.     }
  11. }
复制代码

  • 分析
将A的尾节点与B相连, B的尾节点与A相连
1.png

据图可知当(p, q)→(A, B指针)步频一致时, 会共同到达共有链表的初节点
反转链表(206)

先看代码
  1. class Solution {
  2.     public ListNode reverseList(ListNode head) {
  3.         ListNode prev = null;
  4.         ListNode curr = head;
  5.         while (curr != null){
  6.             ListNode next = curr.next;
  7.             curr.next = prev;
  8.             prev = curr;
  9.             curr = next;
  10.         }
  11.         return prev;
  12.     }
  13. }
复制代码

  • 分析
通过先置哨兵节点, 避免节点数量过少导致null pointer exception
回文链表(234)

先看代码
  1. class Solution {
  2.     public boolean isPalindrome(ListNode head) {
  3.         ListNode fast = head;
  4.         ListNode slow = head;
  5.         while (fast.next != null){
  6.             fast = fast.next;
  7.             slow = slow.next;
  8.             if (fast.next != null){
  9.                 fast = fast.next;
  10.             }
  11.         }
  12.         ListNode rig = reverse(slow);
  13.         ListNode lef = head;
  14.         while (rig != null){
  15.             if (rig.val != lef.val){
  16.                 return false;
  17.             }
  18.             rig = rig.next;
  19.             lef = lef.next;
  20.         }
  21.         return true;
  22.     }
  23.     private ListNode reverse(ListNode node){
  24.         ListNode prev = null;
  25.         while (node != null){
  26.             ListNode next = node.next;
  27.             node.next = prev;
  28.             prev = node;
  29.             node = next;
  30.         }
  31.         return prev;
  32.     }
  33. }
复制代码

  • 分析
通过快慢指针找到中心节点,反转中心节点后链表,取(lef, rig)→(链表头尾节点) 进行回文分析
环形链表(141)

先看代码
  1. public class Solution {
  2.     public boolean hasCycle(ListNode head) {
  3.         ListNode fast = head;
  4.         ListNode slow = head;
  5.         while (fast != null){
  6.             fast = fast.next;
  7.             slow = slow.next;
  8.             
  9.             if (fast != null){
  10.                 fast = fast.next;
  11.             }else return false;
  12.             if (fast == slow) return true;
  13.         }
  14.         return false;
  15.     }
  16. }
复制代码

  • 通过快慢指针, 快指针相对慢指针移动速度为1, 若有环, 必然追上慢指针
环形链表II(142)

先看代码
  1. public class Solution {
  2.     public ListNode detectCycle(ListNode head) {
  3.         ListNode fast = head;
  4.         ListNode slow = head;
  5.         while (fast != null && fast.next != null){
  6.             fast = fast.next.next;
  7.             slow = slow.next;
  8.             if (fast == slow) break;
  9.         }
  10.         if (fast == null || fast.next == null) {
  11.             return null;
  12.         }
  13.         slow = head;
  14.         while (slow != fast){
  15.             fast = fast.next;
  16.             slow = slow.next;
  17.         }
  18.         return slow;
  19.     }
  20. }
复制代码

  • 分析
当快慢指针相遇时, 将慢指针置于head, 同步快慢指针步频, 再次相遇即为入口处
证明
f,  s 为快慢指针移动的步数
a, b分别为为环外长度, 环内长度
由 f = 2s, f = s + n∗b
有 f = 2n∗b, s = n∗b
因 f + a = 2n∗b + a 此时快指针指向环形链表入口
取p = head, 有 (p+a)%(n∗b) == (f+a)%(n∗b) == a
p 和 f在入口相遇
合并两个有序链表(021)

先看代码
[code]class Solution {    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {        ListNode p1 =list1;        ListNode p2 =list2;        ListNode dummy = new ListNode(-1) ;        ListNode res = dummy;        while(p1!= null && p2!=null){            if ( p1.val
您需要登录后才可以回帖 登录 | 立即注册