[剑指offer] 链表篇

JZ6 从尾到头打印链表

  1 /* 从尾到头递归 */
  2 public class JZ6_1
  3 {
  4     private static ArrayList<Integer> res = new ArrayList<>();
  5 
  6     public static ArrayList<Integer> printListFromTailToHead(ListNode listNode)
  7     {
  8         if (listNode != null)
  9         {
 10             printListFromTailToHead(listNode.next);
 11             res.add(listNode.val);
 12         }
 13         return res;
 14     }
 15 }
 16 
 17 /* ArrayList.add(int index, E element) */
 18 public class JZ6_2
 19 {
 20     public static ArrayList<Integer> printListFromTailToHead(ListNode listNode)
 21     {
 22         ArrayList<Integer> res = new ArrayList<>();
 23         while (listNode != null)
 24         {
 25             res.add(0, listNode.val);
 26             listNode = listNode.next;
 27         }
 28         return res;
 29     }
 30 }
 31 
 32 /**/
 33 public class JZ6_3
 34 {
 35     public static ArrayList<Integer> printListFromTailToHead(ListNode listNode)
 36     {
 37         ArrayList<Integer> res = new ArrayList<>();
 38         Stack<Integer> temp = new Stack<>();
 39         while (listNode != null)
 40         {
 41             temp.add(listNode.val);
 42             listNode = listNode.next;
 43         }
 44         while (!temp.isEmpty())
 45         {
 46             res.add(temp.pop());
 47         }
 48         return res;
 49     }
 50 }
 51 
 52 /* 原地反转链表 */
 53 public class JZ6_4
 54 {
 55     public static ArrayList<Integer> printListFromTailToHead(ListNode listNode)
 56     {
 57         ListNode pre = null, cur = listNode, temp = null;
 58         ArrayList<Integer> res = new ArrayList<>();
 59         while (cur != null)
 60         {
 61             temp = cur.next;
 62             cur.next = pre;
 63             pre = cur;
 64             cur = temp;
 65         }
 66         while (pre != null)
 67         {
 68             res.add(pre.val);
 69             pre = pre.next;
 70         }
 71         return res;
 72     }
 73 }
 74 
 75 /* 递归反转链表 */
 76 public class JZ6_5
 77 {
 78     public static ArrayList<Integer> printListFromTailToHead(ListNode listNode)
 79     {
 80         ArrayList<Integer> res = new ArrayList<>();
 81 
 82         ListNode reverseList = reverse(listNode);
 83         while (reverseList != null)
 84         {
 85             res.add(reverseList.val);
 86             reverseList = reverseList.next;
 87         }
 88         return res;
 89     }
 90 
 91     public static ListNode reverse(ListNode node)
 92     {
 93         if (node == null || node.next == null) return node;
 94         ListNode fir = node, sec = node.next;
 95         fir.next = null;
 96         ListNode temp = sec;
 97         ListNode reverse = reverse(sec);
 98         temp.next = fir;
 99         return reverse;
100     }
101 }

JZ24 反转链表

 1 /* 从尾到头递归 */
 2 public class JZ24_1
 3 {
 4     public static ListNode res, tail;
 5 
 6     public static ListNode ReverseList(ListNode listNode)
 7     {
 8         if (listNode != null)
 9         {
10             ReverseList(listNode.next);
11             if (res == null)
12                 res = tail = listNode;
13             else
14             {
15                 tail.next = listNode;
16                 tail = tail.next;
17                 tail.next = null;
18             }
19         }
20         return res;
21     }
22 }
23 
24 /**/
25 public class JZ24_2
26 {
27     public static ListNode ReverseList(ListNode listNode)
28     {
29         ListNode head = new ListNode(-1), tail = head;
30         Stack<Integer> temp = new Stack<>();
31         while (listNode != null)
32         {
33             temp.add(listNode.val);
34             listNode = listNode.next;
35         }
36         while (!temp.isEmpty())
37         {
38             tail.next = new ListNode(temp.pop());
39             tail = tail.next;
40         }
41         return head.next;
42     }
43 }
44 
45 /* 原地反转链表 */
46 public class JZ24_3
47 {
48     public static ListNode ReverseList(ListNode listNode)
49     {
50         ListNode pre = null, cur = listNode, temp = null;
51         while (cur != null)
52         {
53             temp = cur.next;
54             cur.next = pre;
55             pre = cur;
56             cur = temp;
57         }
58         return pre;
59     }
60 }
61 
62 /* 递归反转链表 */
63 public class JZ24_4
64 {
65     public static ListNode ReverseList(ListNode listNode)
66     {
67         if (listNode == null || listNode.next == null) return listNode;
68         ListNode fir = listNode, sec = listNode.next;
69         fir.next = null;
70         ListNode temp = sec;
71         ListNode reverse = ReverseList(sec);
72         temp.next = fir;
73         return reverse;
74     }
75 }

JZ25 合并两个排序的链表

 1 /* 归并 */
 2 public class JZ25_1
 3 {
 4     public static ListNode Merge(ListNode pHead1, ListNode pHead2)
 5     {
 6         ListNode res = new ListNode(-1), tail = res;
 7         while (pHead1 != null && pHead2 != null)
 8         {
 9             if (pHead1.val <= pHead2.val)
10             {
11                 tail.next = pHead1;
12                 pHead1 = pHead1.next;
13             }
14             else
15             {
16                 tail.next = pHead2;
17                 pHead2 = pHead2.next;
18             }
19             tail = tail.next;
20             tail.next = null;
21         }
22         tail.next = pHead1 == null ? pHead2 : pHead1;
23         return res.next;
24     }
25 }
26 
27 /* ⭐递归⭐ */
28 public class JZ25_2
29 {
30     public static ListNode Merge(ListNode pHead1, ListNode pHead2)
31     {
32         if (pHead1 == null) return pHead2;
33         if (pHead2 == null) return pHead1;
34         if (pHead1.val <= pHead2.val)
35         {
36             pHead1.next = Merge(pHead1.next, pHead2);
37             return pHead1;
38         }
39         else
40         {
41             pHead2.next = Merge(pHead1, pHead2.next);
42             return pHead2;
43         }
44     }
45 }

JZ52 两个链表的第一个公共结点

 1 /* 让长链表先走两个链表的长度差,然后再一起走 */
 2 public class JZ52_1
 3 {
 4     public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2)
 5     {
 6         int cnt1 = 0, cnt2 = 0;
 7         ListNode p1 = pHead1, p2 = pHead2;
 8         while (p1 != null)
 9         {
10             cnt1++;
11             p1 = p1.next;
12         }
13         while (p2 != null)
14         {
15             cnt2++;
16             p2 = p2.next;
17         }
18         if (cnt1 > cnt2)
19         {
20             for (int i = 0; i < cnt1 - cnt2; i++)
21                 pHead1 = pHead1.next;
22         }
23         else
24         {
25             for (int i = 0; i < cnt2 - cnt1; i++)
26                 pHead2 = pHead2.next;
27         }
28         while (pHead1 != pHead2)
29         {
30             pHead1 = pHead1.next;
31             pHead2 = pHead2.next;
32         }
33         return pHead1;
34     }
35 }
36 
37 /* ⭐长链表遍历完遍历短链表,短链表遍历完遍历长链表⭐ */
38 public class JZ52_2
39 {
40     public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2)
41     {
42         ListNode p1 = pHead1, p2 = pHead2;
43         while (p1 != p2)
44         {
45             p1 = p1 == null ? pHead2 : p1.next;
46             p2 = p2 == null ? pHead1 : p2.next;
47         }
48         return p1;
49     }
50 }

JZ23 链表中环的入口结点⭐

 1 /*
 2  * 快慢双指针,假设链表环的长度为 m
 3  * 慢指针(每次走一步), 从头节点走到入口节点的距离为 x, 从入口节点走到与快指针相遇的位置为 y (y<m), 即一共走了 x+y 的距离
 4  * 快指针(每次走两步), 因为速度是慢指针的两倍, 所以一共走了 2(x+y) 的距离
 5  * 即 y%m = (x+2y)%m
 6  * 得到 x + y = 整数倍的m
 7  * 所以 x = 整数倍的m - y
 8  * 所以在快慢指针相遇后, 一个指针从头节点出发, 一个指针从相遇位置出发, 每次各自走一步, 当他们相遇时, 即为入口节点
 9  * */
10 public class JZ23_1
11 {
12     public static ListNode EntryNodeOfLoop(ListNode pHead)
13     {
14         ListNode slow = pHead, fast = pHead;
15         while (fast.next != null && fast.next.next != null)
16         {
17             slow = slow.next;
18             fast = fast.next.next;
19             if (slow == fast)
20             {
21                 while (pHead != fast)
22                 {
23                     pHead = pHead.next;
24                     fast = fast.next;
25                 }
26                 return pHead;
27             }
28         }
29         return null;
30     }
31 }

JZ22 链表中倒数最后k个结点

 1 /* 双指针 */
 2 public class JZ22_1
 3 {
 4     public static ListNode FindKthToTail(ListNode pHead, int k)
 5     {
 6         ListNode pre = pHead, last = pHead;
 7         for (int i = 0; i < k; i++)
 8         {
 9             if (last == null) return null;
10             last = last.next;
11         }
12         while (last != null)
13         {
14             last = last.next;
15             pre = pre.next;
16         }
17         return pre;
18     }
19 }

JZ35 复杂链表的复制

 

 1 /* 分成三步 */
 2 public class JZ35_1
 3 {
 4     public static RandomListNode Clone(RandomListNode pHead)
 5     {
 6         RandomListNode head = pHead, res = null, tail = null;
 7         while (head != null)
 8         {
 9             RandomListNode temp = new RandomListNode(-head.label);
10             temp.next = head.next;
11             head.next = temp;
12             head = head.next.next;
13         }
14 
15         head = pHead;
16         while (head != null)
17         {
18             if (head.random == null)
19                 head.next.random = null;
20             else
21                 head.next.random = head.random.next;
22             head = head.next.next;
23         }
24         head = pHead;
25         while (head != null)
26         {
27             if (res == null)
28             {
29                 res = tail = head.next;
30             }
31             else
32             {
33                 tail.next = head.next;
34                 tail = tail.next;
35             }
36             head.next = head.next.next;
37             head = head.next;
38         }
39         return res;
40     }
41 }
42 
43 /* HashMap */
44 public class JZ35_2
45 {
46     public static RandomListNode Clone(RandomListNode pHead)
47     {
48         HashMap<RandomListNode, RandomListNode> map = new HashMap<>();
49         RandomListNode p = pHead, res = null, tail = null;
50         while (p != null)
51         {
52             RandomListNode temp = new RandomListNode(p.label);
53             if (res == null)
54                 res = tail = temp;
55             else
56             {
57                 tail.next = temp;
58                 tail = tail.next;
59             }
60             map.put(p, temp);
61             p = p.next;
62         }
63         p = pHead;
64         tail = res;
65         while (p != null)
66         {
67             if (p.random == null)
68                 tail.random = null;
69             else
70                 tail.random = map.get(p.random);
71             p = p.next;
72             tail = tail.next;
73         }
74         return res;
75     }
76 }

JZ76 删除链表中重复的结点

 1 /* 一边遍历一边构造 */
 2 public class JZ76_1
 3 {
 4     public static ListNode deleteDuplication(ListNode pHead)
 5     {
 6         if (pHead == null || pHead.next == null) return pHead;
 7         ListNode res = new ListNode(-1), tail = res;
 8         while (pHead != null)
 9         {
10             if (pHead.next == null || pHead.val != pHead.next.val)
11             {
12                 tail.next = pHead;
13                 tail = pHead;
14             }
15             while (pHead.next != null && pHead.val == pHead.next.val)
16                 pHead = pHead.next;
17             pHead = pHead.next;
18         }
19         tail.next = null;
20         return res.next;
21     }
22 }
23 
24 /* ⭐递归⭐ */
25 public class JZ76_2
26 {
27     public static ListNode deleteDuplication(ListNode pHead)
28     {
29         if (pHead == null || pHead.next == null) return pHead;
30         if (pHead.val != pHead.next.val)
31         {
32             pHead.next = deleteDuplication(pHead.next);
33             return pHead;
34         }
35         else
36         {
37             ListNode temp = pHead;
38             while (temp != null && temp.val == pHead.val) temp = temp.next;
39             return deleteDuplication(temp);
40         }
41     }
42 }

JZ18 删除链表的节点

 1 /* 遍历 */
 2 public class JZ18_1
 3 {
 4     public static ListNode deleteNode(ListNode head, int val)
 5     {
 6         if (head.val == val)
 7             return head.next;
 8         ListNode pre = head, last = head.next;
 9         while (last != null)
10         {
11             if (last.val == val)
12             {
13                 pre.next = last.next;
14             }
15             last = last.next;
16             pre = pre.next;
17         }
18         return head;
19     }
20 }
21 
22 /* 递归 */
23 public class JZ18_2
24 {
25     public static ListNode deleteNode(ListNode head, int val)
26     {
27         if (head.val == val) return head.next;
28         head.next = deleteNode(head.next, val);
29         return head;
30     }
31 }
posted @ 2023-09-15 10:11  Vivid-BinGo  阅读(3)  评论(0编辑  收藏  举报