算法--链表--移除链表元素

58 阅读2分钟

算法--链表--移除链表元素

链表操作中,可以使用原链表来直接进行删除操作,也可以设置一个虚拟头结点再进行删除操作,接下来看一看哪种方式更方便。

力扣题目链接

题意:删除链表中等于给定值 val 的所有节点。

示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]

示例 2: 输入:head = [], val = 1 输出:[]

示例 3: 输入:head = [7,7,7,7], val = 7 输出:[]

1 解答

先写再看噢~

解答

这个讲得很详细👉代码随想录

1.1 思路-数组与链表的转换

心路历程:

  • 需要写链表,但提供的 head 不是数组么,再看 js 的类型,输入输出都是 ListNode
  • 那写代码,自测的时候直接用数组?显然不行
  • 用链表思维写数组?整一个对象数组?[{val: 'a',next: 1},{val: 'b',next: 2},{val: 'b',next: null}] 去掉一个节点,next 指向再下一个节点,那去掉的这个节点还在数组内... 这么操作起来还是在整数组
  • 先转换吧,把数组变成链表,把抽象的概念实际打印出来
class ListNode {
  constructor(val, next) {
    this.val = val === undefined ? 0 : val;
    this.next = next === undefined ? null : next;
  }
}

// 数组转链表
function arrayToListNode(array) {
  if (array.length === 0) {
    return null; // 如果数组为空,返回 null
  }

  let dummy = new ListNode(0); // 创建一个哑节点作为链表的起点
  let current = dummy; // current 指针用于遍历链表

  for (let val of array) {
    current.next = new ListNode(val); // 为每个数组元素创建新节点并链接到当前节点后面
    current = current.next; // 移动 current 指针到下一个节点
  }

  return dummy.next; // 返回哑节点的下一个节点作为链表的头节点
}

// 链表转数组
function listNodeToArray(head) {
  const array = [];
  let current = head;

  while (current) {
    array.push(current.val); // 将当前节点的值推入数组
    current = current.next; // 移动到下一个节点
  }

  return array; // 返回转换后的数组
}

// 示例
const array = [1, 2, 6];
console.log(arrayToListNode(array));
// ListNode {
//   val: 1,
//   next: ListNode {
//     val: 2,
//     next: ListNode { val: 6, next: null }
//   }
// }

const node = new ListNode(1, new ListNode(2, new ListNode(6)));
console.log(listNodeToArray(node));
// [1, 2, 6]

1.2 思路--链表去除节点

题目转换为

/**
 * @param {ListNode} head
 * @param {number} val
 * @return {ListNode}
 */
var removeElements = function (head, val) {
  // ...
};

const val = 6;
const array = [1, 2, 6, 3, 4, 5, 6];

const node = arrayToListNode(array); // 数组转链表
const returnNode = removeElements(node, val); // 删除节点
const returnArray = listNodeToArray(returnNode); // 链表转数组

console.log(returnArray);

要去掉某个节点时,应当是前一个的指针指向再后一个

var removeElements = function (head, val) {
  // 加一个节点,如果head的第一个节点需要去掉,可以改加的这个节点的next
  const startNode = new ListNode(0, head);

  let currtentNode = startNode;
  while (currtentNode?.next) {
    // 要去掉某个节点时,应当是前一个的指针指向再后一个
    if (currtentNode.next.val === val) {
      currtentNode.next = currtentNode.next.next;
    } else {
      currtentNode = currtentNode.next;
    }
  }

  return startNode.next;
};

时间复杂度 o(n) 空间复杂度 o(1) 测试注意用空数组 [] ,首个节点就需要删掉的数组测试下 [6,6,6]