【路飞】-算法——链表练习

90 阅读1分钟

725. 分隔链表

image.png

【代码】

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode[]}
 */
var splitListToParts = function(head, k) {
    let n = 0;
    let cur = head;
    while (cur != null) {
        n++;
        cur = cur.next;
    }
    let p = Math.floor(n / k), q = n % k;

    const parts = new Array(k).fill(null);
    let curr = head;
    for (let i = 0; i < k, curr != null; i++) {
        parts[i] = curr;
        let partSize = p + (i < q ? 1 : 0);
        for (let j = 1; j < partSize; j++) {
            curr = curr.next;
        }
        const next = curr.next;
        curr.next = null;
        curr = next;
    }
    return parts;
}

分割链表

image.png

【代码】

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} x
 * @return {ListNode}
 */
var partition = function(head, x) {
    let cur = head
    let s = new ListNode(null), s1 = s
    let m = new ListNode(null), m1 = m

    while(cur != null){
        if(cur.val < x) {
            s.next = new ListNode(cur.val)
            s = s.next
        }else{
            m.next = new ListNode(cur.val)
            m = m.next
        }
        cur = cur.next
    }
    m.next = null
    s.next = m1.next

    return s1.next
};

环路检测

image.png

【代码】

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var detectCycle = function(head) {
    if(!head || !head.next) return null

    let slow = head.next, fast = head.next.next
    while(fast){
        if(fast !== slow){
            if(!fast.next){
                return null
            }
            slow = slow.next
            fast = fast.next.next
        }else{
            fast = head
            while(fast !== slow){
                fast = fast.next
                slow = slow.next
            }
            return fast
        }
    }
    return null
};

删除链表的节点

image.png

【代码】

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} val
 * @return {ListNode}
 */
var deleteNode = function (head, val) {
  if (!head) return null
  if (head.val === val && !head.next) return null
  let cur = head,ret = cur
  while (cur && cur.next) {
    let next = cur.next
    if (cur.val === val) return next
    if (next.val === val) {
      cur.next = next.next
      next.next = null
    }
    cur = cur.next
  }
  return ret
};

707. 设计链表

image.png

【代码】

// 单向链表
function ListNode(val,next) {
  this.val = val;
  this.next = next || null;
}
var MyLinkedList = function() {
  this.size = 0
  this.head = null
  
};


MyLinkedList.prototype.getNode = function(index) {
  if (index < 0 || index >= this.size) return null
  let cur = this.head
  for (let i = 0; i < index; i++) {
    cur = cur.next    
  }
  return cur
};
/** 
 * 获取链表中第 index 个节点的值。如果索引无效,则返回-1。
 * @param {number} index
 * @return {number}
 */
MyLinkedList.prototype.get = function (index) {

 if (index < 0 || index >= this.size) return -1
  return this.getNode(index).val
};
/** 
 * 在链表的第一个元素之前添加一个值为 val 的节点。
 * 插入后,新节点将成为链表的第一个节点。
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtHead = function (val) {
  let cur = this.head
  let pre = new ListNode(val, cur)
  this.head = pre
  this.size++
};

/** 
 * 将值为 val 的节点追加到链表的最后一个元素。
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtTail = function(val) {
  if(!this.head) {
      this.head = new ListNode(val)
      this.size++
      return
  }
  let newNode = new ListNode(val)
  let cur = this.head
  while (cur && cur.next) {
    cur = cur.next
  }
  cur.next = newNode
  this.size++
};

/** 
 * 在链表中的第 index 个节点之前添加值为 val  的节点。
 * 如果 index等于链表的长度,则该节点将附加到链表的末尾。
 * 如果 index 大于链表长度,则不会插入节点。
 * 如果index小于0,则在头部插入节点。
 * @param {number} index 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtIndex = function (index, val) {
  if (index <= 0) {
    return this.addAtHead(val)
  }else if (index === this.size) {
    return this.addAtTail(val)
  } else if(index > this.size) {
    return
  }
  let preNode = this.getNode(index - 1) 
  preNode.next = new ListNode(val, preNode.next)
  this.size++
};

/** 
 * 如果索引 index 有效,则删除链表中的第 index 个节点。
 * @param {number} index
 * @return {void}
 */
MyLinkedList.prototype.deleteAtIndex = function(index) {
  if (index < 0 || index >= this.size) return 
  if (index === 0) {
    this.head = this.head.next
    this.size--
    return 
  }
  let indexNode = this.getNode(index)
  let pre = this.getNode(index - 1)
  pre.next = indexNode.next
  this.size--
};
/**
 * Your MyLinkedList object will be instantiated and called as such:
 * var obj = new MyLinkedList()
 * var param_1 = obj.get(index)
 * obj.addAtHead(val)
 * obj.addAtTail(val)
 * obj.addAtIndex(index,val)
 * obj.deleteAtIndex(index)
 */
// TODO 双向链表