链表题目

203 阅读1分钟

反转链表

循环思路

  1. 遍历,一个一个取
  2. 变量,res为返回结果,cur动态改变,用于循环
    1. while循环
    2. 动态改变,cur = cur.next

实验代码

// 第一次循环
res = cur
res.next = null
cur = cur.next

// 第二次循环,后来发现也适用于第一次,a变量是为了保存
let a =cur.next
cur.next = res
res = cur
cur = a
// 总结,正常链表操作是xx.next = yy xx.next.next = zz
// 反转链表,则是cur.next = res res = cur

最终代码

var reverseList = function(head) {
    if (!head)
        return null;
    let res = null, cur = head;
    while (cur) {
        let a =cur.next
        cur.next = res
        res = cur
        cur = a

    }
    return res;
};

递归思路

  1. 原理与循环相同
  2. 只是有一步可以优化?可读性会变差所以不再深究

实验代码(通过)

var reverseList = function(head) {
    let reverse = function(res,cur){
        if(!cur){
            return res
        }
        let next = cur.next
        cur.next = res
        res = cur
        cur = next
        reverse(res,cur)
    }
    return reverse(null,head)
};

区间反转

实验

  1. 出错
  2. 思路
    1. 切成三段
    2. 中间反转
    3. 接上
var reverseBetween = function(head, m, n) {
    let count = n-m
    let pre = null
    let front = null
    let p = head
    if(count===0) {
        return head
    }
    for(let i = 0;i < m-2; i++){
        p = p.next
    }
    front = p.next
    for(let i=0;i<count;i++){
        let next = front.next
        front.next = pre
        pre = front
        front = next
    }
    p.next = front
    return head
};

最终

var reverseBetween = function(head, m, n) {
    let len = n-m
    let front = c = new ListNode()
    front.next = head
    for(let i=0;i<m-1;i++){
        front = front.next
    }
    let first = front.next
    let first2 = front.next
    let pre = null
    for(let i = 0;i<=len;i++){
        let next = first.next
        first.next = pre
        pre = first
        first = next
    }
    front.next = pre
    first2.next = first
    console.log(head,c.next)
    return c.next

};

两个一组反转

k个一组反转