链表-反转链表

leetcode:206. 反转链表

解题思路:

[1,2,3,4,5] 
  1. reverse(head.next) 执行完成后,整个链表就成了这样:1-> 2<-3<-4<-5
  2. 此时2指向了null
  3. 要让1指向null,2指向1,所以 head.next.next = head; head.next=null
  4. 当链表递归反转之后,新的头结点是 last
var reverseList = function(head) {
  if (!head || !head.next) return head
  let last = reverseList(head.next)
  head.next.next = head
  head.next = null
  return last
};
//迭代写法:
var reverseList = function(head) {
  if (!head || !head.next) return head
  let newHead = null
  while (head) {
    let temp = head.next
    head.next = newHead
    newHead = head
    head = temp
  }
  return newHead
};

 反转链表前 N 个节点

解题思路:

[1,2,3,4,5] n=3

1、 n == 1,反转一个元素,就是它本身,同时要记录后驱节点

2、 head 节点在递归反转之后不一定是最后一个节点了,所以要记录后驱 p(第 n + 1 个节点),反转之后将 head 连接上。

let p = null // 后驱节点
var revereseN = function (head, n) {
  if (n == 1) {
    p = head.next //第n+1个节点
    return head
  }
  let last = revereseN(head.next, n - 1) //以head.next为起点,需要反转前n-1个节点
  head.next.next = head
  head.next = p // 让反转之后的 head 节点和后面的节点连起来
  return last
}

leetcode:92. 反转链表 II

解题思路:

  1. 如果 left == 1,就相当于反转链表开头的 n 个元素嘛,即上面代码实现的功能
  2. 如果 left != 1 ,把 head 的索引视为 1,那么就是从第 left翻天 个元素开始反转;如果把 head.next 的索引视为 1 ,反转的区间应该是从第 left - 1 个元素开始的
let p = null // 后驱节点
var revereseN = function (head, n) {
  if (n == 1) {
    p = head.next //第n+1个节点
    return head
  }
  let last = revereseN(head.next, n - 1) //以head.next为起点,需要反转前n-1个节点
  head.next.next = head
  head.next = p // 让反转之后的 head 节点和后面的节点连起来
  return last
}

var reverseBetween = function (head, left, right) {
  if (left == 1) {
    return revereseN(head, right)
  }
  head.next = reverseBetween(head.next, left - 1, right - 1)
  return head
};

leetcode:25. K 个一组翻转链表

1、给定链表头结点,反转整个链表

// 反转以 a 为头结点的链表 : 其实就是「反转 a 到 null 之间的结点」
var reverser = function (a) { 
  let pre = null,
    cur = a,
    nxt = a
  while (cur) {
    nxt = cur.next
    // 逐个结点反转
    cur.next = pre
    pre = cur
    cur = nxt
  }
  return pre // 返回反转后的头结点
}

2、反转 a 到 b 之间的结点   

/** 反转区间 [a, b) 的元素-左闭右开 */
var reverser = function (a, b) {
  let pre = null,
    cur = a,
    nxt = a
  while (cur != b) { //修改这里的终止条件
    nxt = cur.next
    cur.next = pre
    pre = cur
    cur = nxt
  }
  return pre
}

3、实现K个一组翻转链表

var reverser = function (a, b) {
  let pre = null,
    cur = a,
    nxt = a
  while (cur != b) {
    nxt = cur.next
    cur.next = pre
    pre = cur
    cur = nxt
  }
  return pre
}
var reverseKGroup = function (head, k) {
  if (!head) return null
  let a = b = head
  for (let i = 0; i < k; i++) {
    if (!b) return head //没有K个,就不反转
    b = b.next //走到b的区间
  }
  let newHead = reverser(a, b) //反转前K个
  a.next = reverseKGroup(b, k) //递归后链表连接起来
  return newHead

};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值