代码随想录算法训练营第四天 | LeetCode 24 / 19 / 142

LeetCode 24

视频讲解链接: 帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点

思路:

  1. 结合虚拟头结点, 不然每次针对头结点(没有前一个指针指向头结点),还要单独处理
  2. 节点改变的步骤 / 建议结合画图
  3. 节点改变步骤举例[2 1 3 4]
    • 创建一个虚拟节点 0
    • 第一步: 0.next 指向 2
    • 第二步: 2.next 指向 1
    • 第三步: 1.next 指向 3

代码:

var swapPairs = function(head) {
  if(!head) return head
  let dummyHead = new ListNode(0, head)
  let cur = dummyHead
  while(cur.next && cur.next.next){
    let temp1 = cur.next
    let temp2 = cur.next.next
    let temp3 = cur.next.next.next
    cur.next = temp2
    temp2.next = temp1
    temp1.next = temp3

    cur = cur.next.next
  }
  return dummyHead.next
};

LeetCode 19

视频讲解链接: 链表遍历学清楚! | LeetCode:19.删除链表倒数第N个节点

思路:

  1. 使用双遍历, 第一次获取整体链表长度, 求出 n 前一个节点的位置
  2. 第二次找到 n 前一个节点 prev 且 prev.next = prev.next.next

代码:

var removeNthFromEnd = function(head, n) {
  let length = 1
  let loop = head
  while(loop.next){
    loop = loop.next
    length++
  }
  let target = length - n
  if(target === 0){
    return head = head.next
  }
  let preNode = getNode(head, target)
  console.log(head, target)
  preNode.next = preNode.next.next
  return head
};

function getNode(head, index){
  let dummyHead = new ListNode(0, head)
  let cur = dummyHead
  while(index-- > 0){
    cur = cur.next
  }
  return cur
}

思路(双指针):

  1. 设置一个快指针 一个慢指针
  2. 快指针先走 n + 1 步, 然后 快慢指针同时走, 直到快指针为null
  3. 这样慢指针就停在了n前一个节点 prev
  4. 然后 prev.next = prev.next.next

代码

var removeNthFromEnd = function(head, n) {
  let dummyHead = new ListNode(0, head)
  let fast = dummyHead, slow = dummyHead
  while(n--) fast = fast.next
  while(fast.next){
    fast = fast.next
    slow = slow.next
  }
  slow.next = slow.next.next
  return dummyHead.next
};

面试题 02.07. 链表相交

思路:

  1. 先获取两个链表的长度
  2. 让两个链表的尾部对其
  3. 然后同时进行向后遍历并进行比较

代码:

var getIntersectionNode = function(headA, headB) {
  let curA = headA, curB = headB;
  let aLen = 0, bLen = 0;
  while(curA) {
    curA = curA.next;
    aLen++;
  }
  while(curB) {
    curB = curB.next;
    bLen++;
  }

  curA = headA; // 重置curA指针到链表A头部
  curB = headB; // 重置curB指针到链表B头部

  if(aLen < bLen) {
    // 交换curA和curB,这样确保curA始终指向最长的链表
    [curA, curB] = [curB, curA];
    [aLen, bLen] = [bLen, aLen];
  }

  let diff = aLen - bLen;
  while(diff-- > 0) {
    curA = curA.next;
  }
  
  while(curA && curA !== curB) {
    curA = curA.next;
    curB = curB.next;
  }
  return curA;
};

LeetCode 142

视频讲解链接: 把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II

代码

var detectCycle = function (head) {
  if (!head || !head.next) return null;

  let slow = head,
    fast = head;

  while (fast && fast.next) {
    slow = slow.next;
    fast = fast.next.next;
    if (slow === fast) {
      slow = head;
      while (slow !== fast) {
        slow = slow.next;
        fast = fast.next;
      }
      return slow;
    }
  }

  return null;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值