单向链表中间节点
题目描述
求单向链表中间的节点值,如果奇数个节点取中间,偶数个取偏右边的那个值。
输入描述
第一行 链表头节点地址 后续输入的节点数
n
n
n
后续输入每行表示一个节点,格式 节点地址 节点值 下一个节点地址(-1
表示空指针)
输入保证链表不会出现环,并且可能存在一些节点不属于链表。
输出描述
单向链表中间的节点值
示例1
输入
00010 4
00000 3 -1
00010 5 12309
11451 6 00000
12309 7 11451
输出
6
示例2
输入
10000 3
76892 7 12309
12309 5 -1
10000 1 76892
输出
7
解题思路
本题可以使用快慢指针来解决。快指针每次走两步,慢指针每次走一步,当快指针到达链表尾部时,慢指针所指向的节点就是中间节点。我们还可以在代码中添加注释提高代码可读性。
复杂度分析
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是链表节点个数,需要遍历整个链表一次。由于我们只对链表进行了一次遍历,因此时间复杂度是线性的。
空间复杂度: O ( 1 ) O(1) O(1),只需要常数的空间存储快慢指针。这里的空间复杂度不包括函数调用栈的空间,因为我们只使用了常数个变量。
由于本题解决方案比较简单,因此我们在代码中添加注释来提高代码可读性。同时,我们也可以在时间复杂度和空间复杂度分析中添加详细的解释,以更好地理解算法的性能。
参考解题Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String head = scanner.next();
int n = scanner.nextInt();
Node[] nodes = new Node[1000010];
for (int i = 0; i < n; i++) {
String address = scanner.next();
int val = scanner.nextInt();
String next = scanner.next();
nodes[Integer.parseInt(address)] = new Node(address, val, next);
}
Node slow = nodes[Integer.parseInt(head)];
Node fast = nodes[Integer.parseInt(head)];
while (fast != null && fast.next != null) {
slow = nodes[Integer.parseInt(slow.next)];
fast = nodes[Integer.parseInt(nodes[Integer.parseInt(fast.next)].next)];
}
System.out.println(slow.val);
}
static class Node {
String address;
int val;
String next;
public Node(String address, int val, String next) {
this.address = address;
this.val = val;
this.next = next;
}
}
}