题目

Reverse a linked list from position m to n. Do it in-place and in one-pass.

For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4,

return 1->4->3->2->5->NULL.

Note: Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list.

大致意思

给定一个链表,在链表的指定位置中,把部分内容进行反转

解决方案

  • 如果链表不存在、或者 m === n,可以直接return head
if (!head || m === n ) return head;
  • 找到m、n的位置,并且找到m的前一个node,以及n的下一个node。
var node = head;
var index = 1;
var obj;
var pre, next, h, t;

while (node) {
  if (index === m) {
    h = node; // 头的位置
  }

  if (index === n) {
    t = node; // 尾的位置
    next = node.next; // 后一个

    obj = reverse(h, t); // 找到头尾,进行反转
    break;
  }

  if (!h) pre = node; // 前一个位置
  node = node.next;
  index++;
}
  • 将指定位置的内容进行反转
function reverse(head, tail) {
  var list = {};
  tail.next = null;
  var node = head;
  var pre, next;
  var h, t;

  while (node) {
    if (!pre) { // 如果是一个的时候,是没有preNode,所以我们讲这个node的next赋值为next
      pre = node;
      node = node.next;
      pre.next = null;
      t = pre; // 得到这个链表的尾部,方便后续插入
      continue;
    }

    // 将现在的node指向存起来的pre
    next = node.next;
    node.next = pre;
    pre = node;
    node = next;
  }
  return { // 返回整个链表,以及尾部
    node: pre,
    tail: t
  };
}
  • 根据前后内容,进行拼接
if (!pre) {
  head = obj.node;
} else {
  pre.next = obj.node;
}
obj.tail.next = next;

return head;

源代码

var reverseBetween = function(head, m, n) {
  if (!head || m === n ) return head;

  var node = head;
  var index = 1;
  var obj;
  var pre, next, h, t;

  while (node) {
    if (index === m) {
      h = node;
    }

    if (index === n) {
      t = node;
      next = node.next;

      obj = reverse(h, t);
      break;
    }

    if (!h) pre = node;
    node = node.next;
    index++;
  }

  if (!pre) {
    head = obj.node;
  } else {
    pre.next = obj.node;
  }
  obj.tail.next = next;

  return head;
};

function reverse(head, tail) {
  var list = {};
  tail.next = null;
  var node = head;
  var pre, next;
  var h, t;
  var flag = true;

  while (node) {
    if (!pre) {
      pre = node;
      node = node.next;
      pre.next = null;
      t = pre;
      continue;
    }

    next = node.next;
    node.next = pre;
    pre = node;
    node = next;
  }
  return {
    node: pre,
    tail: t
  };
}