返回
揭秘链表算法中的经典难题,轻松驾驭倒数第k个节点查找!
IOS
2023-11-02 06:23:58
在计算机科学的算法领域,链表是一种常见的线性数据结构。链表算法的经典题之一便是查找链表中的倒数第k个节点,看似简单却暗藏玄机。本文将深入解析链表的概念、倒数第k个节点查找的思路和实现,并提供详细的代码示例,帮助你轻松驾驭链表算法的这一难题。
链表的定义与分类
链表是一种由一系列节点组成的线性数据结构,每个节点包含一个数据域和一个指向下一个节点的指针。根据链表中是否存在环形结构,链表可以分为有环链表和无环链表。
倒数第k个节点查找的思路
查找链表中的倒数第k个节点,核心思想是利用两个指针同时遍历链表。第一个指针从链表头部开始遍历,先前进k步;第二个指针紧随其后。当第一个指针遍历到链表尾部时,第二个指针指向的节点即为倒数第k个节点。
实现步骤
1. 创建链表
首先,我们需要创建两个链表:一个无环链表和一个有环链表。
2. 倒数第k个节点查找算法
// 无环链表
public static Node findKthFromEnd_noCycle(Node head, int k) {
if (head == null || k <= 0) {
return null;
}
Node fast = head;
Node slow = head;
// 快指针先前进k步
while (k > 0) {
fast = fast.next;
k--;
}
// 快指针到达链表尾部时,慢指针指向倒数第k个节点
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
// 有环链表
public static Node findKthFromEnd_cycle(Node head, int k) {
if (head == null || k <= 0) {
return null;
}
// 计算链表的长度
int len = 0;
Node cur = head;
while (cur != null) {
len++;
cur = cur.next;
}
// 将k转化为正值
k = len - k;
// 重新遍历链表
cur = head;
while (k > 0) {
cur = cur.next;
k--;
}
return cur;
}
关键细节
- 无环链表的查找过程简单直接,利用两个指针同步遍历链表即可。
- 有环链表的查找需要先计算链表的长度,然后将k转化为正值,再重新遍历链表找到倒数第k个节点。
代码示例
// 无环链表
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
System.out.println(findKthFromEnd_noCycle(head, 2).val); // 输出:4
// 有环链表
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = head; // 形成环
System.out.println(findKthFromEnd_cycle(head, 2).val); // 输出:3
总结
通过本文的详细讲解,你已经掌握了链表算法经典难题——倒数第k个节点查找的思路和实现。无论是无环链表还是有环链表,都可以使用两个指针的同步遍历或计算链表长度的方法高效解决。只要熟练掌握这些技巧,你将能够轻松应对链表算法中的各种挑战。