今天下午腾讯面试考了一道算法题:要求从一个单向链表中删除倒数第n个节点,要求最多只能遍历链表一遍。
面试时我只是给出了思路,晚上画图编码归纳整理记录一下。
思路在上图已经表达的很明确了,其实解题的关键点是利用好n,我们把n当作一把尺子从链表头移动到链表尾后,尺子的左端指的就是我们要删除的倒数第n个节点。
下面贴一下代码实现:
/**
* @param head 链表头节点
* @param n 要删除的倒数第n个节点,数字n
* @return 删除倒数第n个节点后的链表头节点
*/
private static Node deleteNode(Node head, int n) {
int index = 0;
Node node = head;
Node temp = head;
while (temp != null) {
index ++;
temp = temp.next;
if (index > n + 1) {//拿到 倒数 n + 1个 节点
node = node.next;
System.out.println("index= " + index + " node= " + node.data);
}
}
//循环遍历完拿到倒数第n + 1个节点 node
Node deleteNode = node.next;//拿到要删除的倒数第n个节点deleteNode
node.next = deleteNode.next;//删除倒数第n个节点
return head;
}
关于节点类定义代码比较简单,为了方便演示效果,Node类中的data我这边定义为了int 类型,排上序号打印比较方便查看效果
public static class Node{
Node next;
int data;
public Node(int data) {
this.data = data;
}
}
另外再送上两个方法,方便测试效果
/**
* @param n 指定链表的长度
* @return 返回指定长度 n 的链表头节点
*/
private static Node initNode(int n) {
Node head = new Node(1);
Node temp = head;
for (int i= 2; i <= n; i++ ) {
Node node = new Node(i);
temp.next = node;
temp = node;
}
return head;
}
/**
* @param head 要输出打印的链表头结点
*/
private static void printNode(Node head) {
while (head != null) {
System.out.println("node.data = " + head.data);
head = head.next;
}
}
如果您这边有更好的思路也欢迎留言讨论!