leetcode 算法题(链表):快乐数、删除排序链表中的重复元素 II、K 个一组翻转链表、分隔链表

395 阅读2分钟

202. 快乐数

image.png

解题思路
  • 转换为链表是否有环问题
  • 如果有环说明不是快乐数
  • 如果等于1 说明是快乐数
/**
 * @param {number} n
 * @return {boolean}
 */
var isHappy = function(n) {
    
    const getNext = (num) => {
        let result = 0;
        while(num) {
            // 个位数 平方和
            result += (num%10) * (num%10);
            num = Math.floor(num/10);
        }
        return result;
    }

    let pre = n;
    let cur = getNext(n);
    while(cur !== 1) {
        pre = getNext(pre);
        cur = getNext(getNext(cur));
        if(pre === cur) {
            return false;
        }
    }
    return true;
};

82. 删除排序链表中的重复元素 II

image.png

解题思路

  • 使用双指针,pre、cur
  • 判断 pre.next.val 是否 cur.next.val 相等
  • 相等 cur 继续向前移动直到不相等
  • 把 pre.next、cur 指向 cur.next
/**
 * 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 {ListNode}
 */
var deleteDuplicates = function(head) {
    if(!head) {
        return null;
    }
    const ret = new ListNode(null,head);

    let pre = ret;
    let cur = head;
    while(cur && cur.next) {
        //提前判断下一个指针node  值是不是相等
        if(pre.next.val !== cur.next.val) {
            pre = pre.next;
            cur = cur.next;
        } else {
            // 如果相等 就 cur 继续向前移动
            while(cur && cur.next && pre.next.val === cur.next.val) {
                cur = cur.next;
            }
            pre.next = cur.next;
            cur = cur.next;
        }
    }
    return ret.next;
};

25. K 个一组翻转链表

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 reverseKGroup = function(head, k) {
    if(!head) {
        return null;
    }
     const reserve = (head,n) => {
        if(!head) {
            return null;
        }
        let pre = head;
        let cur = head;
        let con = n;
        // 检查够不够n个节点
        while(--n && pre) {
            pre = pre.next;
        }
        if(!pre) {
            return head;
        }
        pre = null;
        // 翻转前k个节点
        while(cur && con-- > 0) {
            const next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        // head: 翻转部分的尾部节点,pre: 翻转部分的头节点
        // cur: 剩余部分的头节点
        head.next = cur;
        return pre;
    }
    let ret = new ListNode(null, head);
    let pre = ret;
    while(true) {
        pre.next = reserve(pre.next,k);
        for(let i=0;i < k && pre;i++) {
            pre = pre.next;
        }
        if(!pre) {
            break;
        }
    }
    return ret.next;
};

86. 分隔链表

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} x
 * @return {ListNode}
 */
var partition = function(head, x) {
    if(!head || !head.next) {
        return head;
    }
    const minHead = new ListNode(null);
    const maxHead = new ListNode(null);

    let cur = head;
    let min = minHead;
    let max = maxHead;

    while(cur) {
        if(cur.val < x) {
            min.next = new ListNode(cur.val);
            min = min.next;
        } else {
            max.next =  new ListNode(cur.val);
            max = max.next;
        }
        cur = cur.next;
    }
   // min.next 小链表的尾部
   // maxHead 为大链表头部
   // 把大链表头部next 指向 小链表尾部
    min.next = maxHead.next;
    // 返回小链表.next 
    return minHead.next;
};
解法二
/**
 * 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} x
 * @return {ListNode}
 */
var partition = function(head, x) {
    if(!head || !head.next) {
        return head;
    }
    const minHead = new ListNode(null);
    const maxHead = new ListNode(null);

    let cur = head;
    let min = minHead;
    let max = maxHead;

    while(cur) {
        if(cur.val < x) {
            min.next = cur;
            min = cur;
        } else {
            max.next =  cur;
            max = cur;
        }
        cur = cur.next;
    }
   // min.next 小链表的尾部
   // maxHead 为大链表头部
   // 把大链表头部next 指向 小链表尾部
    min.next = maxHead.next;
    max.next = null;
    // 返回小链表.next 
    return minHead.next;
};