代码随想录day03

代码随想录day03

链表的定义

 function ListNode(val, next) {
     this.val = (val===undefined ? 0 : val)
     this.next = (next===undefined ? null : next)
 }

203.移除链表元素

移除链表元素【简单】

思路–虚拟头节点

1.如果删除头节点是和其他节点的删除方式不用,所以可以采用虚拟的头节点

/**
 * 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) {
  let node = new ListNode(0,head) // 设置一个虚拟头结点
  let cur = node //定义一个临时的指针来进行后续操作
  while(cur.next !== null) {
    if(cur.next.val === val) {
      cur.next = cur.next.next
      continue
    }
    cur = cur.next
  }
  return node.next

};

重点和收获

1.链表首要想好指针是怎么移动的,是否会移动会访问null即可。
2.因为空指针的错误其实大多是一些if,while中不小心取到了空和循环次数和条件有关这种可以设计简单case比如1-2-3-null这种手动画图走一遍自己的代码就解决了。
3.虚拟头结点的主要目的是为了避免对头结点的特殊处理;这个处理就指的是修改操作。所以可以这样:涉及到对链表修改(如插入,删除,移动)的,都加个dummy,只是遍历取点就可以不用加

707设计链表

代码

class ListNode {
  constructor(val, next) {
    this.val = (val===undefined ? 0 : val)
    this.next = (next===undefined ? null : next)   
  }
}

var MyLinkedList = function() {
  this.size = 0
  this.head = null
  this.dummy = new ListNode(0,this.head) // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
};

/** 
 * @param {number} index
 * @return {number}
 */
MyLinkedList.prototype.get = function(index) {
  if(index<0 || index>this.size-1) return -1
  let cur = this.dummy.next
  while(index--) { // 如果--index 就会陷入死循环
    cur = cur.next
  }
  return cur.val
};

/** 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtHead = function(val) {
  let node = new ListNode(val,this.head)
  this.dummy.next = node
  this.size++
};

/** 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtTail = function(val) {
  let node = new ListNode(val,null)
  let cur = this.dummy
  while(cur.next) {
    cur = cur.next //一直遍历找到尾部节点
  }
  cur.next = node

};

/** 
 * @param {number} index 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtIndex = function(index, val) {
  let node = new ListNode(val,null)
  let cur = this.dummy
  if(index<0 || index>this.size-1) return 
  while(index--) {
    cur = cur.next
  }
  node.next = cur.next
  cur.next = node
  this.size++
};

/** 
 * @param {number} index
 * @return {void}
 */
MyLinkedList.prototype.deleteAtIndex = function(index) {
  if(index<0 || index>this.size-1) return 
  let cur = this.dummy
  while(index--) {
    cur = cur.next
  }
  cur.next = cur.next.next
  this.size--
};

206翻转列表

思路-双指针

1.首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
2.注意 需要一个临时的指针,在cur.next还没赋值的时候提前保存下来,方便后面的使用

代码

/**
 * 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) {
  let pre = null
  let cur = head
  let temp
  while(cur) {
    // 需要一个临时的指针,在cur.next还没赋值的时候提前保存下来,方便后面的使用
    temp = cur.next
    cur.next = pre
    pre = cur
    cur = temp
  }
  return pre
};

收获

1.链表一定要分清节点和指针的概念。 new ListNode()是真实存在的一个节点, head = new ListNode() 相当于 head指针指向了一个真实的节点, node = head, 相当于node和head同时指向了这个真实的节点
2.先写出双指针,再写递归的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值