阅读 82

前端算法面试必刷题系列[53]

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

101. 反转链表 (reverse-linked-list)

标签

  • 链表
  • 简单

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

image.png

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
复制代码

基本步骤

初始的样子大概长这样

null     [1|]-> [2|] -> [3|] -> null
  |(1)    |(2)    |(3)
prev     cur     cur.next
复制代码

其实我们就看成3步

  1. (3) 指向 (1)
  2. (1) (2) 往后移一位
  3. 直到 cur 到 null 那么 prev 就是链表头了,返回就行

写法实现

这个简单的写法实现建议搞懂后作为一个记忆模块

var reverseList = function(head) {
  let [cur, prev] = [head, null];
  while (cur) {
    [cur.next, prev, cur] = [prev, cur, cur.next]
  }
  return prev
};
复制代码

102. 环形链表 (linked-list-cycle)

标签

  • 链表
  • 简单

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给定一个链表,判断链表中是否有环

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

如果链表中存在环,则返回 true 。 否则,返回 false 。

image.png

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
复制代码

基本思想

思路1: 标记

每次走的过程中,用一个 Set 或者数组(Array) 记录下访问过的节点地址,如果有环存在,总会遇到重复节点,当走到的节点落在 Set 中,就说明有环存在。O(n)的时间复杂度

思路2: 快慢指针

设置快慢指针,快指针每次两步,慢指针每次一步,如果有环存在,在某轮总有快指针追上慢指针。O(n)的时间复杂度,也不需要额外的空间 O(1) 即常量内存

写法实现

标记

const hasCycle = function(head) {
  const res = [];
  let cur = head;
  while (cur) {
    if (res.includes(cur)) {
      return true;
    }
    res.push(cur);
    cur = cur.next;
  }
  return false;
};
复制代码

快慢指针

var hasCycle = function(head) {
  let [slow, fast] = [head, head]
  // 快慢指针走到头都没发现有环,就 return false
  while(slow && fast && fast.next) {
    // 快指针每次走两步,慢指针每次一步
    fast = fast.next.next
    slow = slow.next
    // 如果追上,就说明有环
    if (fast === slow) {
      return true
    }
  }
  return false
};
复制代码

疑问: 为什么追上是 fast === slow 有没正好超过而不汇合的情况呢?

其实是没有的,一个一次一步,一个一次两步,你画图就明白了,如果快指针在慢指针后方,diff == 1那么下次就会重合。diff == 2 那么再走一步就变成 diff == 1,注意你在纸上画个图马上就明白,我不帮你画,自己动手印象深。

另外用 set 增加额外空间来判重的方式就不实现了,相对来说也比较简单。

另外向大家着重推荐下这个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友 Or 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考

文章分类
前端
文章标签