数据结构-链表

114 阅读1分钟

1. 从尾到头打印链表

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function printListFromTailToHead(head)
{
    // write code here
    const ans = [];
    while(head) {
        ans.unshift(head.val);
        head = head.next;
    }
    return ans;
}

2. 反转链表

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function ReverseList(pHead)
{
    // write code here
    if(!pHead || !pHead.next) return pHead;
    let a = pHead;
    let b = pHead.next;
    while(b) {
        let c = b.next;
        b.next = a;
        a = b;
        b = c;
    }
    pHead.next = null;
    return a;
}

3. 复杂链表的复制

/*function RandomListNode(x){
    this.label = x;
    this.next = null;
    this.random = null;
}*/
function Clone(pHead)
{
    // write code here
    if(!pHead) return null;
    let map = new Map();
    map.set(null, null);
    let node = pHead;
    while(node) {
        map.set(node, new RandomListNode(node.label));
        node = node.next;
    }
    //复制指针
    node = pHead;
    while(node) {
        map.get(node).next = map.get(node.next);
        map.get(node).random = map.get(node.random);
        node = node.next;
    }
    return map.get(pHead);
    
}

4. 合并两个排序链表

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function Merge(l1, l2)
{
    // write code here
    if(!l1) return l2;
    if(!l2) return l1;
    let dummy = new ListNode(-1);
    let cur = dummy;
    while(l1 && l2) {
        if(l1.val < l2.val) {
            cur.next = new ListNode(l1.val);
            l1 = l1.next;
            cur = cur.next;
        }else {
            cur.next = new ListNode(l2.val);
            l2 = l2.next;
            cur = cur.next;
        }
    }
    if(l1) cur.next = l1;
    if(l2) cur.next = l2;
    return dummy.next;
}

5. 链表倒数第k个节点

/**
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
var findKthToTail = function(pListHead, k) {
    //首先求链表的长度
    let cur = pListHead;
    let n = 0;
    while(cur){
        n++;
        cur = cur.next;
    }
    
    //倒数第k个  第一个节点 走 n - k 步
    cur = pListHead;
    if(k > n) return null;
    for(let i = 0; i < n - k; i ++){
        cur = cur.next;
    }
    return cur;
};

6. 链表中环的入口

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

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var entryNodeOfLoop= function(head) {
    if(!head || !head.next) return null;
    let p1 = head.next;
    let p2 = head.next.next;
    //1. 判断有无环
    while(p1 !=p2){
        if(p2 === null || p2.next === null) return null;
        p1 = p1.next;
        p2 = p2.next.next;
    }
    
    //2. 求环的长度
    let length = 1;
    let tmp = p1;
    p1 = p1.next;
    while(p1 != tmp){
        p1 = p1.next;
        length ++;
    }
    //3. 求入点
    p1 = p2 = head;
    for(let i = 0; i < length; i ++){
        p1 = p1.next;
    }
    
    while(p1 != p2 ){
        p1 = p1.next;
        p2 = p2.next;
    }
    return p1;
};

7. 两个链表的公共节点

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function FindFirstCommonNode(pHead1, pHead2)
{
    // write code here
    let p = pHead1;
    let q = pHead2;
    while( p != q ){
        if(p) p = p.next;
        else p = pHead2;
        if(q) q = q.next;
        else q = pHead1;
    }
    return p;
}

8. 删除重复节点

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function deleteDuplication(pHead)
{
    // write code here
    let dummy = new ListNode(-1);
    dummy.next = pHead;
    
    let p = dummy;
    while(p.next){
        let q = p.next; 
        while(q && p.next.val === q.val) q = q.next; // 找到那个不相等的数字
        // 判断长度是否为1
        if(p.next.next === q) p = p.next;
        else p.next = q;
    }
    return dummy.next;
}

9. 约瑟夫问题

function LastRemaining_Solution(n, m)
{
    // write code here
    if(n === 1) return 0;
    else return (LastRemaining_Solution(n-1, m) + m) % n;
}

image.png