[707] 设计链表(40)

75 阅读2分钟

这题,看解析 有几个用es5写的 都提交报错,只好按照es6的格式写,看解析有个思路很明确,就按照他的思路写,中间代码 我有的优化了. 最后一个删除第n个节点,我自己写出来了,但是是分开index === 0 和不等于0的情况, 但是我记得之前删除倒数第n个节点的时候有用前头部指针, 没有区分,看了几遍不是一会儿事儿

/* 初始化链表节点
因为js没有原生支持链表,所以创建一个节点我们也需要写个方法,把它new出来。一个链表节点能有什么东西呢?只有两个很简单的属性:
val 当前节点的数值
next 下一个节点指向(也可以理解为一个指针) */
class Node {
	constructor(val, next = null) {
		this.val = val;
		this.next = next;
	}
}


class MyLinkedList {
	/* 如果将链表用js对象表示,那它应该具有的最基本的几个属性:
		length 链表长度
		start 头部节点/起始节点 */
	constructor() {
		this.length = 0;
		this.start = null;
	}

	get(index) {
		if (index < 0 || index >= this.length) {
			return -1;
		}
		// 到这一步 说明一定有连表
		let cur = this.start;

		while ((index--) > 0) {
			cur = cur.next;
		}
		return cur.val;
	}

	addAtHead(val) {
		const newNode = new Node(val, this.start);
		// 改变头部节点 和 自身长度
		this.start = newNode;
		this.length++;
	}

	addAtTail(val) {
		const newNode = new Node(val);
		// 和头部插入节点很像,我们只需要多一步操作:找到最后一个节点即可。
		let endNode = this.start;
		while (endNode && endNode.next) {
			endNode = endNode.next;
		}
		// 如果有尾部节点
		if (endNode) {
			endNode.next = newNode;
		} else {
			// 没有尾部节点 相当于 这个连表是空连表 可以直接给this.start
			this.start = newNode;
		}
		// 改变自身长度
		this.length++;
	}

	addAtIndex(index, val) {

		if (index === this.length) {
			return this.addAtTail(val);

		}

		if (index <= 0) {
			return this.addAtHead(val);

		}
		// 只能是在中间
		if (index < this.length) {
			let cur = this.start;
			// >1 说明是找到index的前一位 
			while ((index--) > 1) {
				cur = cur.next;
			}
			const newNode = new Node(val, cur.next);
			cur.next = newNode;

			this.length++;
		}

	}

	// 删除连表中的第n个节点
	deleteAtIndex(index) {
		if (index >= 0 && index < this.length) {

			this.length--;
			// index===0 单独判断 说明 删除第一个节点
			if (index === 0) {
				this.start = this.start.next;
				return;
			}

			let cur = this.start;
			// 循环找到要删除的前一个节点
			while ((index--) > 1) {
				cur = cur.next;
			}
			cur.next = cur.next.next;

		}

	}



};

力扣本题传送门

这个是我参考的题解 JavaScript的单链表实现(es5+es6),包含详细题解