力扣链表题

一、链表

链表+6道前端算法面试高频题解

(一)题目

160. 相交链表(7.3)
  1. 利用集合,先遍历一个链表,将它的节点存到集合中。再遍历另一个链表,看集合中是否有相同节点,如果有,则返回。
  2. 递归法
206. 反转链表(7.3)
  1. 双指针迭代

    利用链表指针pre和cur,改变链表的连接顺序。(改变顺序后,pre和cur都往前挪一步)

    var reverseList = function(head) {
       let cur = head;
       let pre = null;
       let tmp = null;
       while(cur !== null){
           tmp = cur.next;
           cur.next = pre;
           pre = cur;
           cur = tmp;
       }
        return pre; 
    };
    
img
  1. 递归方法

    暂时没有花时间了解

234. 回文链表
  1. 空间复杂度为O(n)的解法:读取链表节点的值放到数组中,再进行判断。

  2. 空间复杂度为O(1)的解法:

    题解中比较多的是递归,另外还有快慢指针、找到链表中间节点再反转后半部分链表等方法。

21. 合并两个有序链表

感觉不难,双指针做法,会判断逻辑,但是不知道怎样合并数组。

(1)方法1:迭代

用ListNode(-1)设立一个指向头节点的节点,用移动指针指向两个链表中较小的节点。

(2)方法2:递归

2. 两数相加(7.5)

感觉逻辑乱了,进位在本次求和就加上了。

19. 删除链表的倒数第N个节点(7.5)

进阶:一趟扫描实现

双指针方法:由于我们需要找到倒数第N个节点, 设置双指针,快指针比满指针超前N个节点,当快指针到达链表末尾时,慢指针到达倒数第N个指针。
对我来说,链表题难的不是逻辑,而是怎样实现,比如设置哑节点、当前节点、快慢指针等

 var removeNthFromEnd = function(head, n) { 
 let dummy = new ListNode(-1,head);
 let fast = dummy;
 let slow = dummy;
 while(n--){
     fast = fast.next;
 } //先向前n步

 while(fast != null && fast.next != null){    
     slow = slow.next;
     fast = fast.next;
 }
 slow.next = slow.next.next;
 return dummy.next;
}; 
24. 两两交换链表中的节点
//非递归方法
var swapPairs = function(head) {
    if(head == null || head.next == null) return head;
    const dummy = new ListNode(-1);
    dummy.next = head;
    let pre = dummy, cur = head;
    while(cur !== null && cur.next !== null){
        pre.next = cur.next;
        cur.next = cur.next.next;
        pre.next.next = cur;
        pre = cur; //这一步很重要,移到后面需要两两交换的节点前面
        cur = cur.next;
    }
    return dummy.next;
};

还有递归解法,没理解透彻。

const swapPairs = function (head) {
    // 递归终止条件
    if (head === null || head.next === null) {
        return head;
    }
    // 获得第 2 个节点
    let newHead = head.next;
    // 将第 1 个节点指向第 3 个节点,并从第 3 个节点开始递归
    head.next = swapPairs(newHead.next);
    // 将第 2 个节点指向第 1 个节点
    newHead.next = head;
    return newHead;
}
92.反转链表II

一般不允许直接修改节点值,而是修改链表连接指向。

(二)链表题型总结

1. 操作单链表某个节点

需要找到链表中某个节点的位置。

通过快慢指针定位到想要操作的节点位置,先让快指针走k步,再让快慢指针一起向后移动。

2. 回文链表、环形链表类型
2.1 回文链表

a. 把链表的值放到数组中判断

b. 利用快慢指针找到中点、反转后半部分链表进行判断

c. 递归

2.2 环形链表

(1)判断是否是环形链表:

​ a. 把节点放到集合中,判断是否重复出现。

​ b. 快慢指针是否相遇,环形链表中快慢指针会相遇。

(2)环形链表II——返回链表入环的第一个节点

​ 需要先找到相遇点,让两个节点分别从链表头和相遇点出发,两个节点的相遇点是环形链表的入口节点。

3. 链表排序、合并链表
//排序链表 自顶向下解法
const merge = (head1, head2) => {
    const dummyHead = new ListNode(0);
    let temp = dummyHead, temp1 = head1, temp2 = head2;
    while (temp1 !== null && temp2 !== null) {
        if (temp1.val <= temp2.val) {
            temp.next = temp1;
            temp1 = temp1.next;
        } else {
            temp.next = temp2;
            temp2 = temp2.next;
        }
        temp = temp.next;
    }
    if (temp1 !== null) {
        temp.next = temp1;
    } else if (temp2 !== null) {
        temp.next = temp2;
    }
    return dummyHead.next;
}

const toSortList = (head, tail) => {
    if (head === null) {
        return head;
    }
    if (head.next === tail) {
        head.next = null;
        return head;
    }
    let slow = head, fast = head;
    while (fast !== tail) {
        slow = slow.next;
        fast = fast.next;
        if (fast !== tail) {
            fast = fast.next;
        }
    }
    const mid = slow;
    return merge(toSortList(head, mid), toSortList(mid, tail));
}

var sortList = function(head) {
    return toSortList(head, null);
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值