我的错误代码
function ListNode(val,next=null){
this.val=val;
this.next=next;
}
var MyLinkedList = function() {
this.head=null
this.tail = this.head
this.size =0
this.virtualHead = new ListNode(-1,this.head)
};
/**
* @param {number} index
* @return {number}
*/
MyLinkedList.prototype.get = function(index) { //第index节点的val是?
if (index < 0 || index >= this.size) return -1 //index不符合规定
let label = -1
let cur = this.virtualHead
while (label !== index){ //不符合,向下找
cur = cur.next
label++
} //等于时,退出
return cur.val;
};
/**
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtHead = function(val) { //在前面加上一个节点
let newHead = new ListNode(val,this.head) //创建新节点,数据是val,next指向这条链表之前的head
this.virtualHead.next = newHead //链表的虚拟节点的next指向此节点的头
this.head = newHead //更新链表头节点
if (!this.head){ //如果头节点不存在
this.tail = newHead //此节点设为尾结点
}
this.size++ //节点数量加一
};
/**
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtTail = function(val) { //后面加节点
let newTail = new ListNode(val,null) //新尾结点
if (!this.tail){ //没有尾结点的话(一个节点都没有)
this.virtualHead.next = newTail //虚拟节点指向尾结点
this.head = newTail //头节点指向新结点
this.tail = newTail //尾结点也指向新节点
} else {
this.tail.next = newTail //原尾结点后面加上此节点
this.tail = newTail //此节点为新的节点
}
this.size++ //数量++
};
/**
* @param {number} index
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtIndex = function(index, val) { //在index出添加this.val=val的节点
if (index > this.size) return //判断是否越界
if (index === this.size) { //加尾
this.addAtTail(val)
return
}
if (index <= 0){ //加头
this.addAtHead(val)
return
}
let newNode = new ListNode(val) //新节点1
let label = 0 //头节点为
let prev, cur = this.head //把链表的头节点复制到两个新节点上
while (label !== index){
prev = cur //prev就是index
cur = cur.next //cur快prev一步
label++
}
prev.next = newNode //index的next指向新节点
newNode.next = cur //新节点的next指向cur节点
this.size++
};
/**
* @param {number} index
* @return {void}
*/
MyLinkedList.prototype.deleteAtIndex = function(index) {
if (index < 0 || index >= this.size) return //越界
let prev, cur = this.virtualHead //虚拟头节点复制到新节点上
let label = -1 //从虚拟节点开始,为-1
while (label !== index){
prev = cur
cur = cur.next
label++
}
if (cur === this.tail) this.tail = prev //tail为倒数第二个,完成了删除操作
prev.next = cur.next //1.不是尾部,跳过cur2.是尾部cur的next==0
cur = null //删除cur
this.size--
};
/**
* 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)
*/
官方的正确代码
var MyLinkedList = function() {
this.size = 0;
this.head = new ListNode(0);
};
MyLinkedList.prototype.get = function(index) {
if (index < 0 || index >= this.size) {
return -1;
}
let cur = this.head;
for (let i = 0; i <= index; i++) {
cur = cur.next;
}
return cur.val;
};
MyLinkedList.prototype.addAtHead = function(val) {
this.addAtIndex(0, val);
};
MyLinkedList.prototype.addAtTail = function(val) {
this.addAtIndex(this.size, val);
};
MyLinkedList.prototype.addAtIndex = function(index, val) {
if (index > this.size) {
return;
}
index = Math.max(0, index);
this.size++;
let pred = this.head;
for (let i = 0; i < index; i++) {
pred = pred.next;
}
let toAdd = new ListNode(val);
toAdd.next = pred.next;
pred.next = toAdd;
};
MyLinkedList.prototype.deleteAtIndex = function(index) {
if (index < 0 || index >= this.size) {
return;
}
this.size--;
let pred = this.head;
for (let i = 0; i < index; i++) {
pred = pred.next;
}
pred.next = pred.next.next;
};
function ListNode(val, next) {
this.val = (val===undefined ? 0 : val)
this.next = (next===undefined ? null : next)
}
第一想法
知道思想,不知道怎么写
困难
一点一点理解,代码还是不过
收获
- TypeError: Cannot read properties of null (reading ‘XXX’)定义为空,找不到就会这样子
- js的一些理解
- 链表的理解
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var removeElements = function(head, val) {
while(head!=null && head.val==val){ //当头等于,去头
head = head.next;
}
let curr = head;
while(curr!==null){ //cur不等于,且不为null
while(curr.next!=null && curr.next.val == val){ //cur.nexr符合,删除
curr.next = curr.next.next; //删除
}
curr = curr.next; //下一个,cur不为val
}
return head;
};
第一想法
知道思想,不知道怎么写
困难
过界
收获
- TypeError: Cannot read properties of null (reading ‘XXX’)定义为空,找不到就会这样子
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
//法一:在搞一个链表
var reverseList = function(head) {
if(head===null||head.next===null) //若没有元素或只有一个元素,直接返回
return head
let newhead=new ListNode(0,null) //新链表虚拟头节点
while(head!==null){
let temp=new ListNode(head.val,newhead.next) //建立一个node,val是head.val,next是虚拟头结点的next
newhead.next=temp; //temp设为头部
head=head.next //下一个
}
return newhead.next;
};
//法二:双指针
var reverseList = function(head) {
if(head===null||head.next===null) //若没有元素或只有一个元素,直接返回
return head
let pre= head
let cur=head.next
pre.next=null //重点
while(cur!==null){
let temp=cur.next //记录cur的下一个
cur.next=pre //指针翻转
pre=cur //pre向前一步
cur=temp //cur跳转
}
return pre;
};
第一想法
法一
困难
法一:
- while(head!==null)与while(head.next!==null)?
head.next是一个节点,若是后者,结果就是【4,3,2,1】,当head.val=5时,while不满足条件。
前者,head.val=5时,最后一行head.next===null不会错。
那TypeError: Cannot read properties of null (reading ‘XXX’)定义为空,到底是啥???
法二:
- pre.next=null
没有的话,报错Error - Found cycle in the ListNode—>链表成为一个圈,一开始就cur和pre互相指。
为啥放while前,因为只断第一次pre的next
- 定义
如果设虚拟节点且定义方法为,let pre=new ListNde(0,null)结果前面会多一个0,【0,5,4,3,2,1】
解决方式:let temp = null, pre = null, cur = head;
收获
- 更熟练链表