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

113 阅读2分钟

剑指 Offer 22. 链表中倒数第k个节点

题目:】 输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

示例 :

给定一个链表: 1->2->3->4->5, 和 k = 2.

返回链表 4->5.

题解:】在常规反转链表的题目上多了一层,返回倒数第k个节点,之前做过返回倒数第k个节点值的一道题,区别在于这道题返回的是当前节点,我们可以新建一个链表,并给链表赋上倒数第k个节点及后续节点的值

代码:

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var getKthFromEnd = function(head, k) {

    let reverHead = reverseListNode(head)
    if(reverHead && !reverHead.next && k===1) return reverHead
    // 新建链表
    let cur = new ListNode(reverHead.val)
    let pre = cur
    while(k-1>0){
        cur.next = new ListNode(reverHead.next.val)
        reverHead = reverHead.next
        cur = cur.next
        k--
    }
    return reverseListNode(pre)
};
// 反转链表
function reverseListNode(head){
    if(head && !head.next) return head
    let pre = null, cur = head
    while(cur){
        let next = cur.next
        cur.next = pre
        pre = cur
        cur = next
    }
    return pre
}

143. 重排链表

题目:】 给定一个单链表 L **的头节点 head ,单链表 L 表示为:

L0 → L1 → … → Ln - 1 → Ln

请将其重新排列后变为:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …

示例1 :

image.png

输入: head = [1,2,3,4]
输出: [1,4,2,3]

示例2 :

image.png

输入: head = [1,2,3,4,5]
输出: [1,5,2,4,3]

题解:

  • 找到链表中间节点
  • 获得中间节点前后两部分链表,将后半部分链表反转获得reverseHead
  • 重组前半部分链表reverseHead

代码:

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {void} Do not return anything, modify head in-place instead.
 */
var reorderList = function(head) {
    if(head && !head.next) return head
    let mid = findMid(head)
    let head2 = mid.next
    mid.next = null
    let reverseHead = reverseListNode(head2)

    let ret = head
    let next1 = null, next2 = null
   while(head && reverseHead) {
       next1 = head.next
       next2 = reverseHead.next

       head.next = reverseHead
       head = next1

       reverseHead.next = head
       reverseHead = next2
   }
    console.log(ret)
};

function findMid(head){
    let slow  = head, fast = head
    while(fast.next && fast.next.next){
        slow = slow.next
        fast = fast.next.next
    }
    return slow
}

function reverseListNode(head){
    if(head && !head.next) return head
    let pre = null, cur = head
    while(cur){
        let next = cur.next
        cur.next = pre
        pre = cur
        cur = next
    }
    return pre
}