代码随想录的第三天
203. 移除链表元素
原链表删除
var removeElements = function(head, val) {
while (head !== null && head.val === val) {
head = head.next
}
let cur = head
while (cur !== null && cur.next !== null) {
if (cur.next.val === val) {
cur.next = cur.next.next
} else {
cur = cur.next
}
}
return head
}
定义虚拟头节点
var removeElements = function(head, val) {
let firstNode = new ListNode()
firstNode.next = head
let cur = firstNode
while (cur !== null && cur.next !== null) {
if (cur.next.val === val) {
cur.next = cur.next.next
} else {
cur = cur.next
}
}
return firstNode.next
};
思路:
1、其实就是找到相同节点,让上一个指针指向下下个指针,跳过去中间完成删除
2、判断头节点是不是第一个,如果是就一直删除;或者就是定义一个虚拟的头节点,然后最后再将头节点去掉
707. 设计链表
单指针:
var MyLinkedList = function() {
this.size = 0
this.head = new ListNode(0)
};
function ListNode(val, next) {
this.val = (val === undefined ? 0 : val)
this.next = (next === undefined ? null : next)
}
/**
* @param {number} index
* @return {number}
*/
MyLinkedList.prototype.get = function(index) {
if (index < 0 || index >= this.size) return -1
let cur = this.head
while (index >= 0) {
cur = cur.next
index--
}
return cur.val
};
/**
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtHead = function(val) {
this.addAtIndex(0, val);
};
/**
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtTail = function(val) {
this.addAtIndex(this.size, val);
};
/**
* @param {number} index
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtIndex = function(index, val) {
if (index > this.size) {
return -1
}
index = Math.max(0, index)
this.size++
let cur = this.head
while (index > 0) {
cur = cur.next
index--
}
let toAdd = new ListNode(val)
toAdd.next = cur.next
cur.next = toAdd
};
/**
* @param {number} index
* @return {void}
*/
MyLinkedList.prototype.deleteAtIndex = function(index) {
if (index < 0 || index >= this.size) return -1
this.size--
let cur = this.head
while (index > 0) {
cur = cur.next
index--
}
cur.next = cur.next.next
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* var obj = new MyLinkedList()
* var param_1 = obj.get(index)
* obj.addAtHead(val)
* obj.addAtTail(val)
* obj.addAtIndex(index,val)
* obj.deleteAtIndex(index)
*/
思路:(暂时只研究单指针)
1、首先是定义指针
2、其次主要三个函数,一个增加节点,删除节点和查询节点
3、增加节点:超出总长度无法增加(因为在链表前加),总长度加一,然后找到需要增加的节点的位置,进行节点增加(注意:需要先将增加的节点指向下一个,再将原先节点指向新增节点)
4、删除节点:总长度减一,找到需要删除的节点,直接指向下下个节点
5、查询节点:找到第index节点然后输出val(为什么不能等于size,因为节点是从0开始的)
206. 反转链表
双指针法
var reverseList = function(head) {
let node = null
let cur = head
while (cur) {
const temp = cur.next
cur.next = node
node = cur
cur = temp
}
return node
};
思路:
1、首先是定义一个虚拟的首节点
2、然后去进行循环链表
3、先将链表的首节点后的链表存储起来,因为后续的操作会影响后续的链表,然后将当前节点指向null,进行首节点的翻转;然后将node节点向后移动一位,将cur向后移动一位
递归
var reverseList = function(head) {
return reverse (head, null)
};
function reverse (cur, pred) {
if (cur === null) return pred
const temp = cur.next
cur.next = pred
pred = cur
cur = temp
return reverse(cur, pred)
}
思路:
模拟双指针遍历,将当前节点的next暂存,然后当前节点指向定义的null,完成了链表的首节点的翻转,然后两个节点都向后走