以下题目都是来自LeetCode,可自行先去实践一下。

:::info 在面试中,链表的题目思维过程是比较简单的,一般对代码的简洁程度及实现能力比较高。 :::

题一:反转链表

题目地址:https://leetcode-cn.com/problems/reverse-linked-list/,题号:206。
image.png
【实现思路】
1.gif

  1. var reverseList = function(head) {
  2. let prev=head, curr=null;
  3. while(prev) {
  4. const temp = prev.next;
  5. prev.next = curr;
  6. curr = prev;
  7. prev = temp;
  8. }
  9. return curr;
  10. };

题二:链表交换相邻元素

题目地址:https://leetcode-cn.com/problems/swap-nodes-in-pairs/,题号:24。
image.png
【实现思路】
这道题思路跟反转链表很像,定义一个临时的节点dummyHead,三个指针temp,node1,node2,交换node1和node2的指向。
1.gif

  1. var swapPairs = function(head) {
  2. if(!head || !head.next) { return head; }
  3. let dummyHead = {},temp=dummyHead;
  4. dummyHead.next = head;
  5. while(temp.next && temp.next.next) {
  6. let node1 = temp.next;
  7. let node2 = temp.next.next;
  8. temp.next = node2;
  9. node1.next = node2.next;
  10. node2.next = node1;
  11. temp = node1;
  12. }
  13. return dummyHead.next;
  14. };

题三:判断链表是否有环

题目地址:https://leetcode-cn.com/problems/linked-list-cycle/,题号:141。题目太长,不做展示。

大致思路有三个:

  • 硬做,对于数据量少的情况,通过设置一个时间,比如0.5s左右,然后一直查找next,看是否会走到null,这是一个解题思路,但不推荐,性能不好。
  • set表。通过遍历整个链表,把已经遍历过的节点都存储在这个set表中,每次保存都先判断这个节点是否存在于这个set表,如果存在就代表有环,否则就代表没有。

    1. var hasCycle = function(head) {
    2. var set = new Set();
    3. while(head) {
    4. set.add(head);
    5. let next = head.next;
    6. if(next && set.has(next)) {
    7. return true;
    8. }
    9. head = next;
    10. }
    11. return false;
    12. };
  • 第三种方法是快慢指针。快慢指针的方式类似于龟兔赛跑,快指针每次走2步,慢指针每次走1步,如果有环,那么最终这两个指针一定会相遇,否则快指针会先到达终点。

1.gif

  1. // 快慢指针
  2. var hasCycle = function(head) {
  3. var fast = slow = head;
  4. while(slow && fast && fast.next) {
  5. slow = slow.next;
  6. fast = fast.next.next;
  7. if(fast === slow) {
  8. return true;
  9. }
  10. }
  11. return false;
  12. };

to be continue…