【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点

个人主页:爱吃炫迈
系列专栏:数据结构与算法
‍座右铭:道阻且长,行则将至

文章目录

  • 反转链表
  • 移除链表元素
  • 两两交换链表中的节点
  • 删除链表的倒数第 N 个结点
  • 总结


反转链表

LeetCode题目:反转链表
思路 :

改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。如下图所示:

【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第1张图片
步骤
【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第2张图片

  • pre:表示当前需要反转节点的前一个节点
  • node:表示当前到达的节点
  1. 定义两个指针prenodepre在前,node在后
  2. 每次让node.next指向pre,实现一次局部反转
  3. 局部反转完成之后,prenode都向前移动一个位置
  4. 循环上述过程,直到node到达链表尾部

代码

var reverseList = function (head) {
  let pre = null; //当前需要翻转节点的前一个节点
  let node = head; //当前需要翻转的节点
  while (node) {
    let nextNode = node.next;
    // 翻转指针
    node.next = pre;
    // pre和node都往后移动
    pre = node;
    node = nextNode;
  }
  // 此时pre是新的头结点,所以返回
  return pre;
};

移除链表元素

LeetCode题目:移除链表元素
思路 :

用迭代的方法删除链表中所有节点值等于特定值的节点。如下图所示:

【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第3张图片

  • 这种情况下的移除操作,就是让节点next指针直接指向下下一个节点就可以了,
  • 那么因为单链表的特殊性,只能指向下一个节点,刚刚删除的是链表的中第二个,和第四个节点,那么如果删除的是头结点又该怎么办呢?

可以设置一个虚拟头结点在进行删除操作:使得头结点和其他节点删除操作相同。

步骤
【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第4张图片

  • dummy node:虚拟头节点
  1. 创建一个虚拟的头节点,并将该节点的next指针指向原链表的头节点。
  2. 判断node.next.val===val是否成立,若成立将node的next指针指向下下个节点,即ndoe.next=node.next.next
  3. node向后移动,直到迭代结束
  4. 最后函数返回虚拟头节点的next指针,真正的头结点

代码

var removeElements = function (head, val) {
  // 虚拟头结点,值为0,指向head
  const dummyNode = new ListNode(0, head);
  let node = dummyNode;
  while (node) {
    if (node.next.val === val) {
      node.next = node.next.next;
      continue;
    }
    node = node.next;
  }
  return dummyNode.next;
};


两两交换链表中的节点

LeetCode题目:两两交换链表中的节点
思路 :

通过迭代的方式实现两两交换链表中的节点。

步骤

  1. 创建虚拟头结点 dummyHead,令 dummyHead.next = head。
    【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第5张图片
  2. temp.next=node2,令temp->node2节点
  • temp:表示当前到达的节点
  • node1:表示temp的后一个节点
  • node2:表示temp的后两个节点
    【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第6张图片
  1. node1.next=node2.next,令node1->node2的下一个节点
    【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第7张图片
  2. node2.next=node1,令node2->node1,完成这步操作后,节点关系变成temp->node2->node1
    【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第8张图片
  3. temp=node1,对链表中的其余节点进行两两交换,直到全部节点都被两两交换。
    【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第9张图片
  4. 重复上面操作,直到 temp 的后面没有节点或者只有一个节点,则没有更多的节点需要交换,因此结束交换。

代码

var swapPairs = function (head) {
  // 虚拟头结点
  const temp = new ListNode(0, head);
  let node = temp;
  while (node.next && node.next.next) {
    let node1 = node.next;
    let node2 = node.next.next;

    node.next = node2;
    node1.next = node2.next;
    node2.next = node1;
    node = node1;
  }
  return temp.next;
};

删除链表的倒数第 N 个结点

LeetCode题目:删除链表的倒数第N个结点
思路1 :

两次遍历链表,第一次遍历得到链表的长度len,第二次遍历删除倒数第n个结点

  • 倒数第n个结点,正向下标为:len-n
  • 若创建了虚拟头结点,则正向下标为:len-n+1
  • 此方法遍历链表两次

代码

var removeNthFromEnd = function (head, n) {
  let len = 0;
  const temp = new ListNode(0, head);
  let node = temp;
  // 链表的节点个数为len
  while (node) {
    node = node.next;
    len++;
  }
  // 被删节点的下标为deleNode
  let deleNode = len - n;
  let lastNode = null;
  node = temp;
  for (let i = 0; i < deleNode; i++) {
    //将当前节点赋值给上一个节点
    lastNode = node;
    //将当前节点更新为下一个节点
    node = node.next;
  }
  // 赋值上一个节点的下一个节点为当前节点的下一个节点即可删除该节点
  lastNode.next = node.next;
  return temp.next;
};

思路2

双指针:

  • 创建虚拟结点
  • 我们可以使用两个指针 firstsecond 同时对链表进行遍历;
  • secondfirst超前且相隔n个结点。当 second 遍历到链表的末尾(null)时,first 就恰好处于倒数第 n+1(3)个节点。
  • 此方法遍历链表一次

动图演示
【LeetCode刷题笔记】反转链表、移除链表元素、两两交换链表中的节点、删除链表的倒数第N个结点_第10张图片
步骤

  1. 设置虚拟节点dummyHead指向 head
  2. 设定双指针 firstsecond,初始都指向虚拟节点 dummyHead
  3. 移动second ,直到 firstsecond 之间相隔的元素个数为 n
  4. 同时移动 firstsecond,直到 second指向的为 NULL
  5. first 的下一个节点指向下下个节点

代码

var removeNthFromEnd = function (head, n) {
  const dummyHead = new ListNode(0, head);
  let first = dummyHead;
  let second = dummyHead;
  for (let i = 0; i <= n; i++) {
    //n2移动n+1次
    second = second.next;
  }

  while (second) {
  // first和second同时移动
    first = first.next;
    second = second.next;
  }
  // 令first指向first的下下个结点,即删除first的下个结点
  first.next = first.next.next;
  return dummyHead.next;
};


总结

希望我的文章能对你学习链表的知识有所帮助!

你可能感兴趣的:(数据结构与算法,链表,leetcode,数据结构,算法)