找出链表中倒数第n个元素
方案1: 双指针
找出链表中倒数第n个元素的解决方案是使用双指针
- 将两个指针都定位到头部节点
- 先移动第一个指针到n
- 两个指针同时移动,直到第一个指针指向最后一个节点,此时,另外一个指针就位于倒数第n个节点。
示例代码如下
class Node {
constructor(data, next = null) {
this.data = data;
this.next = next;
}
}
class LinkedList {
constructor() {
this.head = null;
}
insertAtEnd(data) {
let newNode = new Node(data);
if(!this.head){
this.head = newNode;
} else {
let current = this.head;
while(current.next){
current = current.next;
}
current.next = newNode;
}
}
//找到链表中倒数第n个元素
findFromLast(n) {
//定义双指针,链表中的指针直接指向第一个元素。
let mainPtr = this.head;
let refPtr = this.head;
//先移动第一个指针到n
//也就是遍历n次
let count = 0;
while (count < n) {
//边界处理
if(refPtr == null) {
console.log(`${n} is greater than the no. of nodes in list`);
return;
}
refPtr = refPtr.next;
count++;
}
//我们假设链表长度为len
//那对于倒数第n个元素也就是第len-n个元素
//当refPtr为null的时候,对于指针refPtr,我们正好在这里是遍历了len-n次
while(refPtr != null){
mainPtr = mainPtr.next;
refPtr = refPtr.next;
}
console.log(`Node no. ${n} from last is ${mainPtr.data}`);
return mainPtr
}
};
let list = new LinkedList();
for(let i = 0 ; i<5 ; i++){
list.insertAtEnd(i);
}
list.findFromLast(3);
方案2: 增加空间复杂度,不推荐
遍历所有node节点并存放到map中,key为index值,value为第index个节点,那么遍历结束以后,index为node节点总数,那么第index-n个元素就是我们需要的结果。
增加空间复杂度只适应于数据量较小的情况,这里只是提供一种思路,不推荐使用
根据以上代码其他代码不变,只修改findFromLast
findFromLast(n) {
let linkedMap = {}
let refNode = this.head
let index = 0
while (refNode != null) {
linkedMap[`${index}`] = refNode
refNode = refNode.next
index++
}
if (index < n) {
console.log(`${n} is greater than the no. of nodes in list`);
} else {
console.log(`Node no. ${n} from last is ${linkedMap[index - n].data}`);
return linkedMap[index - n]
}
}