面试题答案
一键面试从性能角度考虑,对于频繁的插入和删除操作,不建议使用普通数组,而是选择 LinkedList
(链表)这种数据结构。
原因:普通数组在插入或删除元素时,尤其是在数组中间位置操作时,需要移动大量元素以保持连续性,时间复杂度为 $O(n)$。而链表插入和删除元素仅需修改指针指向,时间复杂度为 $O(1)$。
JavaScript 没有内置的链表数据结构,但可以通过对象模拟链表:
// 模拟链表节点
function ListNode(val) {
this.val = val;
this.next = null;
}
// 模拟链表
function LinkedList() {
this.head = null;
this.tail = null;
// 插入到链表尾部
this.addToTail = function(val) {
const newNode = new ListNode(val);
if (!this.head) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
this.tail = newNode;
}
};
// 删除指定值的节点
this.deleteNode = function(val) {
let current = this.head;
let prev = null;
while (current) {
if (current.val === val) {
if (prev === null) {
this.head = current.next;
} else {
prev.next = current.next;
}
if (current === this.tail) {
this.tail = prev;
}
return;
}
prev = current;
current = current.next;
}
};
}
使用示例:
const list = new LinkedList();
list.addToTail(1);
list.addToTail(2);
list.addToTail(3);
list.deleteNode(2);
如果非要使用数组,可以利用 JavaScript 的 splice
方法,但要尽量避免在数组中间频繁操作。例如在数组头部插入元素:
let arr = [1, 2, 3];
arr.unshift(0); // 在头部插入元素,时间复杂度 O(n),但比在中间插入性能好
在尾部插入元素使用 push
,时间复杂度为 $O(1)$:
arr.push(4);
删除元素使用 pop
(删除尾部元素)或 shift
(删除头部元素),时间复杂度为 $O(1)$:
arr.pop();
arr.shift();
如果要删除指定位置元素,使用 splice
,但尽量减少在中间位置删除操作:
arr.splice(1, 1); // 删除索引为1的元素