Front end common algorithm questions (linked list)

Time:2022-5-25

Inversion problem

2021.02.11

No. 25 K flip linked list in groups

I’ll give you a linked list. Each group of k# nodes will be flipped. Please return to the flipped linked list.

K is a positive integer whose value is less than or equal to the length of the linked list.

If the total number of nodes is not an integer multiple of K , keep the last remaining nodes in the original order.

 

Example:

Here’s the list: 1 – > 2 – > 3 – > 4 – > 5

When k = 2, it should return: 2 – > 1 – > 4 – > 3 – > 5

When k = 3, it should return: 3 – > 2 – > 1 – > 4 – > 5

 

explain:

Your algorithm can only use the extra space of constants.
You can’t simply change the value inside the node, but you need to actually exchange nodes.

Source: leetcode
Link:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=25 lang=javascript
 *
 *[25] turn over the linked list in groups of K
 */

// @lc code=start
/**
 * 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) {
    //Linked list to array
    const  list2Arr = head => {
        const a = [head.val];
        while(head.next) {a.push(head.next.val);head = head.next;}
        return a;
    }
    //Array to linked list
    const arr2List = arr => {
        let head = new ListNode(arr[0]);
        let cur = head;
        for(let i=1; i < arr.length; i++) {
            cur.next = new ListNode(arr[i]);
            cur = cur.next;
        };
        return head;
    };
    //The K nodes can be cut into arrays
    const kReverse = (a,k) => {
        const r = [];
        let cnt = 0;
        while(a.length >= k + cnt)
        {
            let tmp = a.slice(cnt, cnt+k);
            tmp.reverse();
            tmp.map( (x)=> r.push(x));
            cnt += k;
        }
        a.slice(cnt).map( (x)=> r.push(x));
        return r;
    }
    
    return arr2List(kReverse(list2Arr(head), k));
};
Scheme II:
/*
 * @lc app=leetcode.cn id=25 lang=javascript
 *
 *[25] turn over the linked list in groups of K
 */

// @lc code=start
/**
 * 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) {
    let cur = head;
    let count = 0;
    //Find the first and last nodes of k elements to be reversed
    while(cur != null && count != k){
        cur = cur.next;
        count++;
    }
    //Enough K nodes to reverse
    if(count == k){
        //Recursively link the following K inverted chain header nodes
        cur = reverseKGroup(cur,k);
        while(count != 0){
            count--;
            //Reverse linked list
            let tmp = head.next;
            head.next = cur;
            cur = head;
            head = tmp;
        }
        head = cur;
    }
    return head;
};
Scheme III:
/*
 * @lc app=leetcode.cn id=25 lang=javascript
 *
 *[25] turn over the linked list in groups of K
 */

// @lc code=start
/**
 * 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;
    //Reverse linked list
    let reverse = (a,b) => {
        let pre;
        let cur = a;
        let next = b;
        while(cur != b){
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
    //K elements to be reversed in the inversion interval a-b
    let a = head;
    let b = head;
    for(let i = 0;i < k;i++){
        //Less than k, no need to reverse
        if(!b) return head;
        b = b.next;
    }
    //Reverse the first k elements
    let newHead = reverse(a,b);
    //Recursive link subsequent reverse linked list
    a.next = reverseKGroup(b,k);
    return newHead;
};
Scheme 4:
/*
 * @lc app=leetcode.cn id=25 lang=javascript
 *
 *[25] turn over the linked list in groups of K
 */

// @lc code=start
/**
 * 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) {
    let stack = [];
    let preHead = new ListNode(0);
    let pre = preHead;
    //Circular link subsequent reverse linked list
    while(true){
        let count = 0;
        let tmp = head;
        while(tmp && count < k){
            stack.push(tmp);
            tmp = tmp.next;
            count++;
        }
        //If there are less than k, link directly and return the rest of the linked list
        if(count != k){
            pre.next = head;
            break;
        }
        //Out of stack is inversion
        while(stack.length > 0){
            pre.next = stack.pop();
            pre = pre.next;
        }
        pre.next = tmp;
        head = tmp;
    }
    return preHead.next;
};
Scheme 5:
/*
 * @lc app=leetcode.cn id=25 lang=javascript
 *
 *[25] turn over the linked list in groups of K
 */

// @lc code=start
/**
 * 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) {
      const myReverse = (head, tail) => {
        let prev = tail.next;
        let p = head;
        while (prev !== tail) {
            const nex = p.next;
            p.next = prev;
            prev = p;
            p = nex;
        }
        return [tail, head];
    }
    const hair = new ListNode(0);
    hair.next = head;
    let pre = hair;

    while (head) {
        let tail = pre;
        //Check whether the length of the remaining part is greater than or equal to K
        for (let i = 0; i < k; ++i) {
            tail = tail.next;
            if (!tail) {
                return hair.next;
            }
        }
        const nex = tail.next;
        [head, tail] = myReverse(head, tail);
        //Reconnect the sub linked list to the original linked list
        pre.next = head;
        tail.next = nex;
        pre = tail;
        head = tail.next;
    }
    return hair.next;
};

There are five solutions: 1. Using array to solve is relatively cumbersome, which needs to be switched to array and then cut back; 2. Recursive correlation scheme, using stack and iteration for analysis; 3. It is ingenious to reduce the complexity to a constant level by using the dummy front node


2021.02.12

No.61 rotating linked list

Given a linked list, rotate the linked list and move each node of the linked list to the right by # K # positions, where # K # is a non negative number.

Example 1:

Input: 1 – > 2 – > 3 – > 4 – > 5 – > null, k = 2
Output: 4 – > 5 – > 1 – > 2 – > 3 – > null
Explanation:
Rotate 1 step to the right: 5 – > 1 – > 2 – > 3 – > 4 – > null
Rotate 2 steps to the right: 4 – > 5 – > 1 – > 2 – > 3 – > null
Example 2:

Input: 0 – > 1 – > 2 – > null, k = 4
Output: 2 – > 0 – > 1 – > null
Explanation:
Rotate 1 step to the right: 2 – > 0 – > 1 – > null
Rotate 2 steps to the right: 1 – > 2 – > 0 – > null
Rotate 3 steps to the right: 0 – > 1 – > 2 – > null
Rotate 4 steps to the right: 2 – > 0 – > 1 – > null

Source: leetcode
Link:https://leetcode-cn.com/problems/rotate-list
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=61 lang=javascript
 *
 *[61] rotating linked list
 */

// @lc code=start
/**
 * 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 rotateRight = function(head, k) {
    //Linked list to array
    const  list2Arr = head => {
        if(!head) return [];
        const a = [head.val];
        while(head.next) {a.push(head.next.val);head = head.next;}
        return a;
    }
    //Array to linked list
    const arr2List = arr => {
        if(arr.length == 0) return null;
        let head = new ListNode(arr[0]);
        let cur = head;
        for(let i=1; i < arr.length; i++) {
            cur.next = new ListNode(arr[i]);
            cur = cur.next;
        };
        return head;
    };
    //Array position change
    const arrRotate = (a, k) => {
        const len = a.length;
        const hashTable = {};
        for(let i=0; i< a.length; i++) {
            hashTable[(i+k) % len] = a[i]
        };
        return Object.values(hashTable) 
    };
    return arr2List(arrRotate(list2Arr(head), k));
};
Scheme II:
/*
 * @lc app=leetcode.cn id=61 lang=javascript
 *
 *[61] rotating linked list
 */

// @lc code=start
/**
 * 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 rotateRight = function (head, k) {
    if (!head || k === 0) return head;  //  Special judgment
    let p = head, len = 1;
    while (p.next) {
        p = p.next;
        len++;
    }
    p.next = head; //  End to end
    k = len - k % len; //  Process the distance to move
    while (k--) p = p.next;
    head = p.next;  //  Head points to the len - K + 1 node, which is the answer
    p.next = null;  //  Cut off the relationship between len - K and Len - K + 1
    return head;
}
Scheme III:
/*
 * @lc app=leetcode.cn id=61 lang=javascript
 *
 *[61] rotating linked list
 */

// @lc code=start
/**
 * 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 rotateRight = function(head, k) {
    if(head===null||head.next===null)return head;
    let len = 0;// Linked list length
    let p = head;
    let first = head;// First node
    let stack = [];// Auxiliary stack
    while(p){
        stack.push(p);
        p = p.next;
        len++;
    }
    p = stack.pop();
    for(let i = 1;i<=k%len;i++){
        p.next = first;
        stack.unshift(p);
        first = p;
        p = stack.pop();
        p.next = null;
    }
    return first;
};
Scheme 4:
/*
 * @lc app=leetcode.cn id=61 lang=javascript
 *
 *[61] rotating linked list
 */

// @lc code=start
/**
 * 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 rotateRight = function(head, k) {
       var order = new ListNode(0,head); //  Copy of head linked list
       var fast = new ListNode(0,head); //  Quick pointer
       var slow = new ListNode(0,head); //  Slow pointer
       var count = 0; //  Linked list length
   
       While (order & & order. Next) {// loop to find the length of the linked list
           order = order.next;
           count ++;
       }
       var n = k % count; //  Because repeated operations occur when k > the length of the linked list. Find the remainder of K and remove the repetition
   
       For (VaR I = 0; I < n; I + +) {// the fast pointer takes n steps first
           fast = fast.next;
       }
       While (fast & & fast. Next) {// fast pointer and slow pointer operation of linked list
           fast = fast.next;
           slow = slow.next;
       }
       
       //Two step operation
       //First, disconnect the penultimate K% count element from the penultimate (k% count-1) element
       var resultPre = slow. next; //  Sequence number 2 returns the starting position of the result set
       var result = resultPre; //  No. 3 result set of the last return
       slow. next = null; //  Disconnect the linked list
       //Second, talk about the tail and head links of the linked list
       while(resultPre && resultPre.next) {
           resultPre = resultPre.next
       }
       if (resultPre){ 
           resultPre. next = head; //  Case 1: if there is any change after rotating the linked list, splice the linked list 
       }
       else {
           result = head;  //  Case 2: if there is no change after rotating the linked list, return to the original linked list
       }
       return result;
   };
Scheme 5:
/*
 * @lc app=leetcode.cn id=61 lang=javascript
 *
 *[61] rotating linked list
 */

// @lc code=start
/**
 * 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}
 */
const rotateRight = (head, k) => {
    if (!head || !head.next) return head
    let curr = head, n = 0
    //Traverse the linked list to calculate its length
    while (++n && curr.next) curr = curr.next
    K = k% n // weight removal
    //Move linked list right
    while (k--) {
        curr = head
        while (curr.next.next) curr = curr.next
        //Here curr is the broken position of the linked list, that is, the penultimate item
        curr. next. Next = head // the last item in the linked list points to the head to form a ring
        head = curr. Next // locate the new header node
        curr. Next = null // break the linked list link
    }
    return head
}

There are five ideas for this topic: 1. Hash table storage, hash convergence and dispersion by using the position sorting of the array to generate a new linked list; 2. The linked list forms a ring and is cut at the corresponding position; 3. Stack assisted processing loop clipping position; 4. The fast and slow pointers are processed according to the position spacing of the double pointers, and the new cut position is recorded with the other two pointers; 5. Routine exhaustive, step by step


2021.02.13

No.92 flip linked list-ii

Reverse the linked list from position m to n. Please use one scan to complete the inversion.

explain:
1 ≤ m ≤ n ≤ linked list length.

Example:

Input: 1 – > 2 – > 3 – > 4 – > 5 – > null, M = 2, n = 4
Output: 1 – > 4 – > 3 – > 2 – > 5 – > null

Source: leetcode
Link:https://leetcode-cn.com/problems/reverse-linked-list-ii
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=92 lang=javascript
 *
 *[92] reverse linked list II
 */

// @lc code=start
/**
 * 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} m
 * @param {number} n
 * @return {ListNode}
 */
var reverseBetween = function(head, m, n) {
    //Linked list to array
    const  list2Arr = head => {
        if(!head) return [];
        const a = [head.val];
        while(head.next) {a.push(head.next.val);head = head.next;}
        return a;
    }
    //Array to linked list
    const arr2List = arr => {
        if(arr.length == 0) return null;
        let head = new ListNode(arr[0]);
        let cur = head;
        for(let i=1; i < arr.length; i++) {
            cur.next = new ListNode(arr[i]);
            cur = cur.next;
        };
        return head;
    };
    //Array M = > n flip
    const reversePosition = (a, m, n) => {
        return [...a.slice(0,m-1), ...a.slice(m-1,n).reverse(), ...a.slice(n)]
    };
    return arr2List(reversePosition(list2Arr(head),m,n));
};
Scheme II:
/*
 * @lc app=leetcode.cn id=92 lang=javascript
 *
 *[92] reverse linked list II
 */

// @lc code=start
/**
 * 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} m
 * @param {number} n
 * @return {ListNode}
 */
var reverseBetween = function(head, m, n) {
    //Step1 = > double pointers P1, P2 keep a fixed spacing
    const dummyHead = new ListNode(0, head);
    let p1 = p2 = head;
    let step2 = n - m;
    while (step2-- > 0) {
        p2 = p2.next;
    }
    let step1 = m - 1;
    let tmpHead = p1;
    while (step1-- > 0) {
        tmpHead = p1;
        p1 = p1.next;
        p2 = p2.next;
    }
    //The pointer P1: Du doesn't work
    if (p1 == head) {
        tmpHead = dummyHead;
    }
    //Step3 = > tail interpolation
    let tmp = p1;
    while (tmp != p2) {
        tmp = p1.next;
        p1.next = tmp.next;
        tmp.next = tmpHead.next;
        tmpHead.next = tmp;
    }
    return dummyHead.next;
};

Two solutions: 1. Turn it into an array and splice it with slice and reverse of the array; 2. Double pointer + tail interpolation method, using the exchange of head and tail pointers


2021.02.14

No.206 reverse linked list

Reverse a single linked list.
Example:
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL

Scheme I:
/*
 * @lc app=leetcode.cn id=206 lang=javascript
 *
 *[206] reverse linked list
 */

// @lc code=start
/**
 * 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 reverseList = function(head) {
    //Linked list to array
    const  list2Arr = head => {
        if(!head) return [];
        const a = [head.val];
        while(head.next) {a.push(head.next.val);head = head.next;}
        return a;
    }
    //Array to linked list
    const arr2List = arr => {
        if(arr.length == 0) return null;
        let head = new ListNode(arr[0]);
        let cur = head;
        for(let i=1; i < arr.length; i++) {
            cur.next = new ListNode(arr[i]);
            cur = cur.next;
        };
        return head;
    };
    //Array M = > n flip
    const reverseList = (a) => {
        return a.reverse()
    };
    return arr2List(reverseList(list2Arr(head)));
};
Scheme II:
/*
 * @lc app=leetcode.cn id=206 lang=javascript
 *
 *[206] reverse linked list
 */

// @lc code=start
/**
 * 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 reverseList = function(head) {
    let prev = null;
    let curr = head;
    while (curr) {
        const next = curr.next;
        curr.next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
};
Scheme III:
/*
 * @lc app=leetcode.cn id=206 lang=javascript
 *
 *[206] reverse linked list
 */

// @lc code=start
/**
 * 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 reverseList = function(head) {
    if (head == null || head.next == null) {
        return head;
    }
    const newHead = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return newHead;
};

Three methods: 1. Convert to an array and use the reverse of the array; 2. Iteration; 3. Recursion


Summary:
  1. The common problem of reversing the linked list is to use the three pointers of the linked list for related inversion. The common problems are the related deformation of the head pointer, tail pointer and replacement pointer. You can use stack and other data structures for iteration or recursion;
  2. A clever way to solve the inversion problem is to convert it into an array, use the relevant API of the array for processing, and then turn the array into a linked list

Separate merge

2021.02.18

No.21 merge two ordered linked lists

Merge the two ascending linked lists into a new ascending linked list and return. The new linked list is composed of all nodes of a given two linked lists.

Front end common algorithm questions (linked list)
 

Example 1:

Input: L1 = [1,2,4], L2 = [1,3,4]
Output: [1,1,2,3,4,4]
Example 2:

Input: L1 = [], L2 = []
Output: []
Example 3:

Input: L1 = [], L2 = [0]
Output: [0]
 

Tips:

The number of nodes in the two linked lists ranges from [0, 50]
-100 <= Node.val <= 100
L1 and L2 are arranged in non decreasing order

Source: leetcode
Link:https://leetcode-cn.com/problems/merge-two-sorted-lists
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=21 lang=javascript
 *
 *[21] merge two linked lists
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var mergeTwoLists = function(l1, l2) {
    if(!l1) return l2;
    if(!l2) return l1;

    while(l1 != null && l2 != null) {
        if(l1.val <= l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        } else {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
};
Scheme II:
/*
 * @lc app=leetcode.cn id=21 lang=javascript
 *
 *[21] merge two linked lists
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var mergeTwoLists = function(l1, l2) {
    let prev = new ListNode(-1),
        head = prev;
    while(l1 != null && l2 != null) {
        if(l1.val <= l2.val) {
            head.next = l1;
            l1 = l1.next;
        } else {
            head.next = l2;
            l2 = l2.next;
        }
        head = head.next;
    }

    head.next = l1 === null ? l2 : l1;

    return prev.next;
};
Scheme III:
/*
 * @lc app=leetcode.cn id=21 lang=javascript
 *
 *[21] merge two linked lists
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var mergeTwoLists = function(l1, l2) {
    //Linked list to array
    const  list2Arr = head => {
        if(!head) return [];
        const a = [head.val];
        while(head.next) {a.push(head.next.val);head = head.next;}
        return a;
    }
    //Array to linked list
    const arr2List = arr => {
        if(arr.length == 0) return null;
        let head = new ListNode(arr[0]);
        let cur = head;
        for(let i=1; i < arr.length; i++) {
            cur.next = new ListNode(arr[i]);
            cur = cur.next;
        };
        return head;
    };
    //Merge sort of two arrays
    const mergeArr = (a1,a2) => {
        return [...a1,...a2].sort((a,b) => a-b);
    }
    
    return arr2List(mergeArr(list2Arr(l1), list2Arr(l2)));
};

There are three schemes: 1. Recursion, using implicit stack to merge linked lists; 2. Iteration, using double pointers for iterative judgment; 3. Convert to array merge ascending sort


2021.02.21

No.23 merge K ascending linked lists

Give you a linked list array, each linked list has been arranged in ascending order.

Please merge all linked lists into an ascending linked list and return to the merged linked list.

Example 1:

Input: lists = [[1,4,5], [1,3,4], [2,6]]
Output: [1,1,2,3,4,4,5,6]
Explanation: the linked list array is as follows:
[
 1->4->5,
 1->3->4,
 2->6
]
Combine them into an ordered linked list.
1->1->2->3->4->4->5->6
Example 2:

Input: lists = []
Output: []
Example 3:

Input: lists = [[]]
Output: []
 

Tips:

k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= listsi <= 10^4
Lists [i] in ascending order
lists[i]. The total length should not exceed 10 ^ 4

Source: leetcode
Link:https://leetcode-cn.com/problems/merge-k-sorted-lists
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=23 lang=javascript
 *
 *[23] merge K ascending linked lists
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode[]} lists
 * @return {ListNode}
 */
var mergeKLists = function(lists) {
    //Linked list to array
    const  list2Arr = head => {
        if(!head) return [];
        const a = [head.val];
        while(head.next) {a.push(head.next.val);head = head.next;}
        return a;
    }
    //Array to linked list
    const arr2List = arr => {
        if(arr.length == 0) return null;
        let head = new ListNode(arr[0]);
        let cur = head;
        for(let i=1; i < arr.length; i++) {
            cur.next = new ListNode(arr[i]);
            cur = cur.next;
        };
        return head;
    };
    //The K nodes can be cut into arrays
    const mergeArr = lists => {
        const r = [];
        lists.forEach(list => r.push(...list2Arr(list)))
        return r.sort((a,b) => a-b);
    }
    return arr2List(mergeArr(lists));
};
Scheme II:
/*
 * @lc app=leetcode.cn id=23 lang=javascript
 *
 *[23] merge K ascending linked lists
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode[]} lists
 * @return {ListNode}
 */
var mergeKLists = function(lists) {
    //Merge two linked lists
    const mergeTwoLists = function(l1, l2) {
        let prev = new ListNode(-1),
            head = prev;
        while(l1 != null && l2 != null) {
            if(l1.val <= l2.val) {
                head.next = l1;
                l1 = l1.next;
            } else {
                head.next = l2;
                l2 = l2.next;
            }
            head = head.next;
        }
    
        head.next = l1 === null ? l2 : l1;
    
        return prev.next;
    };
    //Divide and conquer
    const merge = (lists, l, r) => {
        if (l == r) return lists[l];
        if (l > r) return null;
        const mid = (l + r) >> 1;
        return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
    };

    return merge(lists, 0, lists.length - 1);
};
Scheme III:
/*
 * @lc app=leetcode.cn id=23 lang=javascript
 *
 *[23] merge K ascending linked lists
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode[]} lists
 * @return {ListNode}
 */
var mergeKLists = function(lists) {
    let queue = new PriorityQueue();
    lists.forEach(list => {
        if(list) queue.enqueue(list, list.val)
    });

    let res = new ListNode(-1);
    let cur = res;
    while(!queue.isEmpty()) {
        cur.next = queue.dequeue();
        cur = cur.next;
        if(cur.next) queue.enqueue(cur.next, cur.next.val);
    }
    return res.next;
}

class Node {
    constructor(val, priority) {
        this.val = val;
        this.priority = priority;
    }
}

class PriorityQueue {
    constructor() {
        this.values = [];
    }

    enqueue(val, priority) {
        let node = new Node(val, priority);
        this.values.push(node);
        this.bubbleUp();
    }

    dequeue() {
        let max = this.values[0];
        let end = this.values.pop();
        if(this.values.length) {
            this.values[0] = end;
            this.bubbleDown();
        }
        return max.val;
    }
    
    isEmpty() {
        return !this.values.length;
    }
    
    bubbleUp(index = this.values.length - 1) {
        if(index <= 0) return;
        let parentIndex = Math.floor((index - 1) / 2);
        if(this.values[index].priority <= this.values[parentIndex].priority) {
            [this.values[index], this.values[parentIndex]] = [this.values[parentIndex], this.values[index]];
            this.bubbleUp(parentIndex);
        }
    }
    
    bubbleDown(index = 0, swapIndex = null) {
        let leftIndex = index * 2 + 1,
            rightIndex = index * 2 + 2,
            length = this.values.length;

        if(leftIndex < length) {
            if(this.values[leftIndex].priority <= this.values[index].priority) {
                swapIndex = leftIndex;
            }
        }

        if(rightIndex < length) {
            if((swapIndex === null && this.values[rightIndex].priority <= this.values[index].priority) || (swapIndex !== null && this.values[rightIndex].priority <= this.values[leftIndex].priority)) {
                swapIndex = rightIndex;
            }
        }

        if(swapIndex !== null) {
            [this.values[index], this.values[swapIndex]] = [this.values[swapIndex], this.values[index]];
            this.bubbleDown(swapIndex, null);
        }
    }
};

There are three solutions: 1. Use the array to solve it, and finally turn the array into a linked list; 2. Combined with the combination of two linked list schemes, the divide and conquer algorithm is used to optimize; 3. Construct priority queue for optimization, and use space for time


2021.02.22

No.86 separate linked list

Give you a head node of the linked list and a specific value X. please separate the linked list so that all nodes less than x appear before nodes greater than or equal to X.

You should keep the initial relative position of each node in both partitions.

 

Example 1:

Front end common algorithm questions (linked list)

Input: head = [1,4,3,2,5,2], x = 3
Output: [1,2,2,4,3,5]
Example 2:

Input: head = [2,1], x = 2
Output: [1,2]
 

Tips:

The number of nodes in the linked list is within [200]
-100 <= Node.val <= 100
-200 <= x <= 200

Source: leetcode
Link:https://leetcode-cn.com/problems/partition-list
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=86 lang=javascript
 *
 *[86] separate linked list
 */

// @lc code=start
/**
 * 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) {
    let a = new ListNode(0),
        b = new ListNode(0);
    const ahead = a,
          bhead = b;
    while(head) {
        if(head.val < x) {
            a.next = head;
            a = a.next;
        } else {
            b.next = head;
            b = b.next;
        }
        head = head.next;
    }
    a.next = bhead.next;
    b.next = null;
    return ahead.next;
};
Scheme II:
/*
 * @lc app=leetcode.cn id=86 lang=javascript
 *
 *[86] separate linked list
 */

// @lc code=start
/**
 * 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) {
    //Linked list to array
    const  list2Arr = head => {
        if(!head) return [];
        const a = [head.val];
        while(head.next) {a.push(head.next.val);head = head.next;}
        return a;
    }
    //Array to linked list
    const arr2List = arr => {
        if(arr.length == 0) return null;
        let head = new ListNode(arr[0]);
        let cur = head;
        for(let i=1; i < arr.length; i++) {
            cur.next = new ListNode(arr[i]);
            cur = cur.next;
        };
        return head;
    };
    //Array sorting
    const arrSort = (arr, x) => {
        return [...arr.filter(a => a < x), ...arr.filter(a => a >= x)];
    };
    
    return arr2List(arrSort(list2Arr(head), x))
};

There are two solutions: 1. Merge after dividing into large and small linked lists; 2. Sorting using array API


2021.03.02

No.725 separate linked list

Given a linked list whose head node is root, write a function to separate the linked list into k consecutive parts.

The length of each part should be as equal as possible: the length difference between any two parts cannot exceed 1, that is, some parts may be null.

These K parts should be output in the order they appear in the linked list, and the length of the front part should be greater than or equal to the length of the back part.

Returns a list of linked lists that meet the above rules.

Example: 1 – > 2 – > 3 – > 4, k = 5 / / 5 result [[1], [2], [3], [4], null]

Example 1:

Input:
root = [1, 2, 3], k = 5
Output: [[1], [2], [3], [], []]
Explanation:
Input and output parts should be linked lists, not arrays.
For example, Val = 1, root next. val = 2, oot. next. next. Val = 3, and root next. next. next = null。
The first output [0] is output [0] val = 1, output[0]. next = null。
The last element output [4] is null, which represents that the last part is an empty linked list.
Example 2:

Input:
root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3
Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
Explanation:
The input is divided into several consecutive parts, and the length difference of each part is no more than 1 The length of the front part is greater than or equal to the length of the rear part.
 

Tips:

Length range of root: [0, 1000]
Size range of each node entered: [0, 999]
Value range of K: [1, 50]

Source: leetcode
Link:https://leetcode-cn.com/problems/split-linked-list-in-parts
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme:
/*
 * @lc app=leetcode.cn id=725 lang=javascript
 *
 *[725] separate linked list
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} root
 * @param {number} k
 * @return {ListNode[]}
 */
var splitListToParts = function (root, k) {
    // 1.  Get the length of the linked list
    const getRootLength = root => {
        let n = 0;
        while (root) {
            n++;
            root = root.next;
        };
        return n;
    };
    // 2.  Analysis of linked list segmentation
    //Item B is a + 1; K-B is a
    const len = getRootLength(root),
        a = ~~(len / k),
        b = len % k;
    // 3.  Split linked list
    const r = []; //  Returned linked list array
    //Circular linked list 
    for(let m = 1;m<=k;m++) {
        if(!root) {
            r.push(null);
            continue;
        }
        let p1 = root,
            p2 = root,
            num = a;
        if(m<=b) {
            while(num-->0) p2 = p2.next;
        } else {
            num -=1;
            while(num-->0) p2 = p2.next;
        };
        //Processing P2 is null
        if(!p2) {
            r.push(p1);
            root = null;
            continue;
        }
            
        
        root = p2.next;
        p2.next = null;
        r.push(p1);

    }
    return r;
};

The key is to separate K, judge different segmentation lengths, and pay attention to the treatment of boundary conditions


Summary:
  1. The merging and segmentation of linked list mainly involves the construction of new linked list, which needs to be split and combined according to the requirements. The common construction of linked list includes double pointer method and stack method
  2. In particular, because JS does not have its own linked list structure, it can convert the linked list into an array and use the relevant API to process it

Delete node

2021.03.04

No.203 remove linked list elements

Delete the value equal to the given value in the linked listval All nodes.
Example:
Input: 1->2->6->3->4->5->6, val = 6
Output: 1->2->3->4->5

Scheme:
/*
 * @lc app=leetcode.cn id=203 lang=javascript
 *
 *[203] remove linked list elements
 */

// @lc code=start
/**
 * 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} val
 * @return {ListNode}
 */
var removeElements = function(head, val) {
    if(!head) return null;

    let p = phead = new ListNode(null);
    p.next = head;
    while(p.next) {
        if(p.next.val == val) {
            p.next = p.next.next;
        } else {
            p = p.next;
        }
    }
    return phead.next;
};

The construction of linked list uses dummy nodes to construct head pointers for double pointer traversal


2021.03.06

No.19 delete the penultimate node of the linked list

Give you a linked list, delete the penultimate node of the linked list, and return the head node of the linked list.

Advanced: can you try using one scan?

 

Example 1:
Front end common algorithm questions (linked list)

Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]
Example 2:

Input: head = [1], n = 1
Output: []
Example 3:

Input: head = [1,2], n = 1
Output: [1]
 

Tips:

The number of nodes in the linked list is Sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

Source: leetcode
Link:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=19 lang=javascript
 *
 *[19] delete the penultimate node of the linked list
 */

// @lc code=start
/**
 * 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} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
    let p = head, q = head, m = phead = new ListNode(head);
    m.next = head;
    //Change the Q pointer to q = head Next... Next has n next
    for( let _n = n; _n > 0; _n-- ) {
        q = head.next;
        head = head.next;
    };

    //Stop traversal when q is null
    while(q) {
        p = p.next;
        q = q.next;
        m = m.next;
    };

    //Delete the node at this time Q
    p = p.next;
    m.next = p;

    return phead.next;
};
Scheme II:
/*
 * @lc app=leetcode.cn id=19 lang=javascript
 *
 *[19] delete the penultimate node of the linked list
 */

// @lc code=start
/**
 * 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} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
  let lastN = 0;

  const recursion = (head) => {
    if (!head) {
      return null;
    }

    const next = recursion(head.next);

    lastN++;

    if (lastN === n) {
      head = next;
    }

    if (lastN === n + 1) {
      head.next = next;
    }

    return head;
  };
  
  return recursion(head);
};
Scheme III:
/*
 * @lc app=leetcode.cn id=19 lang=javascript
 *
 *[19] delete the penultimate node of the linked list
 */

// @lc code=start
/**
 * 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} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
  const nowHead = [head];
  
  let tempHead = head;
  while (tempHead.next) {
    nowHead.push(tempHead.next);
    tempHead = tempHead.next;
  }
  
  let lastN = 0;

  let isHead = true;

  while (nowHead.length) {
    lastN++;
    const now = nowHead.pop();

    if (lastN - 1 === n) {
      isHead = false;
      now.next = now.next.next;
    }
  }

  if (isHead) {
    head = head.next;
  }

  return head;
};

There are three schemes: 1. Speed pointer. Set the speed pointer spacing to n to traverse; 2. Recursion; 3. Iteration


2021.03.09

No.82 delete duplicate elements in the sorting linked list II

Given a sort linked list, delete all nodes with duplicate numbers, and only keep the numbers of , which do not appear repeatedly in the original linked list.

Example 1:

Input: 1 – > 2 – > 3 – > 3 – > 4 – > 4 – > 5
Output: 1 – > 2 – > 5
Example 2:

Input: 1 – > 1 – > 1 – > 2 – > 3
Output: 2 – > 3

Source: leetcode
Link:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme:
/*
 * @lc app=leetcode.cn id=82 lang=javascript
 *
 *[82] delete duplicate Element II in the sorting linked list
 */

// @lc code=start
/**
 * 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;
    let h = p = new ListNode(head),
        q = head;
    h.next = head;
    p.next = head
    while (q && q.next) {
        if ( q.val == q.next.val) {
            while(q.next && q.val == q.next.val) q = q.next; 
            p.next = q.next;
        } else {
            p = p.next;
        }
        q = q.next;
    }
    return h.next;
};

Double pointer processing requires attention to boundary processing


2021.03.10

No.83 delete duplicate elements in the sorting linked list

Given a sort linked list, delete all duplicate elements so that each element appears only once.

Example 1:

Input: 1 – > 1 – > 2
Output: 1 – > 2
Example 2:

Input: 1 – > 1 – > 2 – > 3 – > 3
Output: 1 – > 2 – > 3

Source: leetcode
Link:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=83 lang=javascript
 *
 *[83] delete duplicate elements in the sorting linked list
 */

// @lc code=start
/**
 * 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;

    let h = p = new ListNode(head),
        q = head;
    h.next = head;
    p.next = head;

    while(q && q.next) {
        if(q.next.val == q.val) {
            while(q.next && q.next.val == q.val) {
                q = q.next;
            }
            p.next = q;
        }
        p = p.next;
        q = q.next;
    };

    return h.next;
};
Scheme II:
/*
 * @lc app=leetcode.cn id=83 lang=javascript
 *
 *[83] delete duplicate elements in the sorting linked list
 */

// @lc code=start
/**
 * 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 || !head.next) return head;

    head.next = deleteDuplicates(head.next);

    if(head.next.val == head.val) {
        head.next = head.next.next; 
    }

    return head;
};

With question 82, there are two schemes: 1. Speed pointer, or single pointer traversal; 2. Recursion


2021.03.11

Delete node in No.237 linked list

Please write a function so that it can delete the given (non end) node in a linked list. The only parameter passed in to the function is the node to be deleted.

 

There is an existing linked list — head = [4,5,1,9], which can be expressed as:

Front end common algorithm questions (linked list)

 
Example 1:

Input: head = [4,5,1,9], node = 5
Output: [4,1,9]
Explanation: given the second node with a value of {5} in your linked list, after calling your function, the linked list should be 4 – > 1 – > 9
Example 2:

Input: head = [4,5,1,9], node = 1
Output: [4,5,9]
Explanation: given the third node with a value of {1} in your linked list, after calling your function, the linked list should be 4 – > 5 – > 9
 

Tips:

The linked list contains at least two nodes.
The values of all nodes in the linked list are unique.
The given node is a non end node and must be a valid node in the linked list.
Don’t return any results from your function.

Source: leetcode
Link:https://leetcode-cn.com/problems/delete-node-in-a-linked-list
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme:
/*
 * @lc app=leetcode.cn id=237 lang=javascript
 *
 *[237] delete nodes in the linked list
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} node
 * @return {void} Do not return anything, modify node in-place instead.
 */
var deleteNode = function(node) {
    if(!node) return null;

    node.val = node.next.val;
    node.next = node.next.next;
};

For the scheme of deleting a node without a head node, it is necessary to replace the current value and then delete the next node value


Summary:
  1. The most common scheme to delete a node is to traverse and delete the fast and slow pointer, and explore the fast pointer. The slow pointer is used as the last link list path to control the node accordingly;
  2. Additional space such as recursion, iteration and stack can also be used in exchange for corresponding time efficiency

Special linked list

2021.03.15

No.141 circular linked list

Given a linked list, judge whether there are links in the linked list.

If there is a node in the linked list that can be reached again by continuously tracking the next pointer, there is a ring in the linked list. In order to represent the rings in a given linked list, we use the integer POS to represent the position where the tail of the linked list is connected to the linked list (the index starts from 0). If POS is – 1, there is no ring in the linked list. Note: POS is not passed as a parameter, but only to identify the actual situation of the linked list.

Returns true if there are links in the linked list. Otherwise, false is returned.

 

Advanced:

Can you solve this problem with O (1) (i.e., constant) memory?

 

Example 1:
Front end common algorithm questions (linked list)

Input: head = [3,2,0, – 4], POS = 1
Output: true
Explanation: there is a ring in the linked list, and its tail is connected to the second node.
Example 2:
Front end common algorithm questions (linked list)

Input: head = [1,2], POS = 0
Output: true
Explanation: there is a ring in the linked list, and its tail is connected to the first node.
Example 3:

Input: head = [1], POS = – 1
Output: false
Explanation: there are no links in the linked list.
 

Tips:

The number range of nodes in the linked list is [0, 104]
-105 <= Node.val <= 105
POS is – 1 or a valid index in the linked list.

Source: leetcode
Link:https://leetcode-cn.com/problems/linked-list-cycle
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=141 lang=javascript
 *
 *[141] circular linked list
 */

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

/**
 * @param {ListNode} head
 * @return {boolean}
 */
var hasCycle = function(head) {
    if(!head) return false;
    let hash = new Map();

    while(head) {
        if(hash.has(head)) return true;
        hash.set(head, true);
        head = head.next;
    }

    return false;
};
Scheme II:
/*
 * @lc app=leetcode.cn id=141 lang=javascript
 *
 *[141] circular linked list
 */

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

/**
 * @param {ListNode} head
 * @return {boolean}
 */
var hasCycle = function(head) {
  let fast = head;
  let slow = head;
  while (fast) {                        
    if (fast.next == null) return false; 
    slow = slow.next;                 
    fast = fast.next.next;             
    if (slow == fast) return true;   
  }
  return false;
};
Scheme III:
/*
 * @lc app=leetcode.cn id=141 lang=javascript
 *
 *[141] circular linked list
 */

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

/**
 * @param {ListNode} head
 * @return {boolean}
 */
var hasCycle = function(head) {
    try {
        JSON.stringify(head)
        return false
    } catch {
        return true
    }
};

There are three solutions: 1. Construct hash table; 2. Fast and slow pointer judgment; 3. Take advantage of JSON The of stringify cannot be referenced circularly


2021.04.26

NO.160 cross linked list

Write a program to find the starting node where two single linked lists intersect.
As shown in the following two linked lists:
Front end common algorithm questions (linked list)

The intersection begins at node C1.

 

Example 1:
Front end common algorithm questions (linked list)

Input: intersectval = 8, lista = [4,1,8,4,5], listb = [5,0,1,8,4,5], skipa = 2, skipb = 3
Output: reference of the node with value = 8
Input explanation: the value of intersection node is 8 (note that if two linked lists intersect, it cannot be 0). Starting from their respective headers, linked list a is [4,1,8,4,5], and linked list B is [5,0,1,8,4,5]. In a, there are 2 nodes before the intersection node; In B, there are three nodes before the intersection node.
 

Example 2:
Front end common algorithm questions (linked list)

Input: intersectval = 2, lista = [0,9,1,2,4], listb = [3,2,4], skipa = 3, skipb = 1
Output: reference of the node with value = 2
Input explanation: the value of intersection node is 2 (note that if two linked lists intersect, it cannot be 0). Starting from the respective header, linked list a is [0,9,1,2,4], and linked list B is [3,2,4]. In a, there are 3 nodes before the intersection node; In B, there is one node before the intersection node.
 

Example 3:
Front end common algorithm questions (linked list)

Input: intersectval = 0, lista = [2,6,4], listb = [1,5], skipa = 3, skipb = 2
Output: null
Input explanation: from the respective header, linked list a is [2,6,4], and linked list B is [1,5]. Because the two linked lists do not intersect, intersectval must be 0, and skipa and skipb can be any value.
Explanation: the two linked lists do not intersect, so null is returned.
 

be careful:

If the two linked lists have no intersection, null is returned
After returning the results, the two linked lists must still maintain their original structure.
It can be assumed that there is no loop in the whole linked list structure.
The program shall meet the O (n) time complexity as much as possible, and only use o (1) memory.

Source: leetcode
Link:https://leetcode-cn.com/problems/intersection-of-two-linked-lists
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=160 lang=javascript
 *
 *[160] intersecting linked list
 */

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

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function (headA, headB) {
  if (!headA || !headB) return null;

  let pA = headA;
  while (pA) {
    let pB = headB;

    while (pB) {
      if (pA === pB) return pA;
      pB = pB.next;
    }

    pA = pA.next;
  }
};
Scheme II:
/*
 * @lc app=leetcode.cn id=160 lang=javascript
 *
 *[160] intersecting linked list
 */

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

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function (headA, headB) {
    if (!headA || !headB) return null;

    const hashmap = new Map();

    let pA = headA;
    while (pA) {
        hashmap.set(pA, 1);
        pA = pA.next;
    }

    let pB = headB;
    while (pB) {
        if (hashmap.has(pB)) return pB;
        pB = pB.next;
    }
};
Scheme III:
/*
 * @lc app=leetcode.cn id=160 lang=javascript
 *
 *[160] intersecting linked list
 */

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

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function (headA, headB) {
  if (!headA || !headB) return null;

  let pA = headA,
      pB = headB;
  while(pA != pB) {
    pA = pA === null ? headB : pA.next;
    pB = pB === null ? headA : pB.next;
  }

  return pA;
};
Scheme 4:
/*
 * @lc app=leetcode.cn id=160 lang=javascript
 *
 *[160] intersecting linked list
 */

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

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function (headA, headB) {
      let aNum = 0
    let bNum = 0
    let short = headA
    let long = headB
    let tempA = headA
    let tempB = headB
    while (short) {
        aNum += 1
        short = short.next
    }
    while (long) {
        bNum += 1
        long = long.next
    }
    if (aNum > bNum) {
        let dig = aNum - bNum
        for (let i = 0; i < dig; i++) {
            tempA = tempA.next
        }
        while (tempA) {
            if(tempA == tempB) {
                return tempA
            } else {
                tempA = tempA.next
                tempB = tempB.next
            }
        }
    }
    if (aNum < bNum) {
        let dig = bNum - aNum
        for (let i = 0; i < dig; i++) {
            tempB = tempB.next
        }
        while (tempA) {
            if(tempA == tempB) {
                return tempA
            } else {
                tempA = tempA.next
                tempB = tempB.next

            }
        }
    }
    if (aNum = bNum) {
        while (tempA) {
            if(tempA == tempB) {
                return tempA
            } else {
                tempA = tempA.next
                tempB = tempB.next

            }
        }
    }
};

There are four schemes: 1. Violent solution, let a go to B; 2. First traverse to generate hash table, and then judge; 3. Form a cross ring linked list and cross traverse; 4. First traverse and calculate the longest table, let the longest table go first, and then judge synchronously


2021.04.27

No.142 circular linked list II

Given a linked list, return the first node from the linked list into the ring. If the linked list is acyclic, null is returned.
In order to represent the rings in a given linked list, we use the integer POS to represent the position where the tail of the linked list is connected to the linked list (the index starts from 0). If POS is – 1, there is no ring in the linked list. Note that POS is only used to identify the ring and is not passed to the function as a parameter.

Note: it is not allowed to modify the given linked list.

Advanced:

Can you use o (1) space to solve this problem?
 

Example 1:
Front end common algorithm questions (linked list)

Input: head = [3,2,0, – 4], POS = 1
Output: returns the linked list node with index 1
Explanation: there is a ring in the linked list, and its tail is connected to the second node.
Example 2:
Front end common algorithm questions (linked list)

Input: head = [1,2], POS = 0
Output: returns the linked list node with index 0
Explanation: there is a ring in the linked list, and its tail is connected to the first node.
Example 3:
Front end common algorithm questions (linked list)

Input: head = [1], POS = – 1
Output: return null
Explanation: there are no links in the linked list.
 

Tips:

The number of nodes in the linked list is within the range [0, 104]
-105 <= Node.val <= 105
The value of POS is – 1 or a valid index in the linked list

Source: leetcode
Link:https://leetcode-cn.com/problems/linked-list-cycle-ii
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=142 lang=javascript
 *
 *[142] circular linked list II
 */

// @lc code=start
/**
 * 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) return null;
    let hash = new Map();

    while(head) {
        if(hash.has(head)) return head;
        hash.set(head);
        head = head.next;
    }

    return null;
};
Scheme II:
/*
 * @lc app=leetcode.cn id=142 lang=javascript
 *
 *[142] circular linked list II
 */

// @lc code=start
/**
 * 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 === null) {
        return null;
    }
    let slow = head, fast = head;
    while (fast !== null) {
        slow = slow.next;
        if (fast.next !== null) {
            fast = fast.next.next;
        } else {
            return null;
        }
        if (fast === slow) {
            let ptr = head;
            while (ptr !== slow) {
                ptr = ptr.next;
                slow = slow.next;
            }
            return ptr;
        }
    }
    return null;
};

There are two schemes: 1. Use the map or set data structure to record the linked list, and the spatial complexity is O (n); 2. Using the speed pointer to calculate the encounter distance, the storage space of the data structure is saved, and the space complexity is O (1)


2021.05.10

No.143 rearrange linked list

Given a single linked list L: l0 → L1 →… → ln-1 → LN, rearrange it to: l0 → ln → L1 → ln-1 → L2 → LN-2 →

You can’t simply change the value inside the node, but you need to actually exchange nodes.

Example 1:

Given the linked list 1 – > 2 – > 3 – > 4, rearrange it to 1 – > 4 – > 2 – > 3
Example 2:

Given the linked list 1 – > 2 – > 3 – > 4 – > 5, rearrange it to 1 – > 5 – > 2 – > 4 – > 3

Source: leetcode
Link:https://leetcode-cn.com/problems/reorder-list
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=143 lang=javascript
 *
 *[143] rearrange linked list
 */

// @lc code=start
/**
 * 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) {
    //Flip linked list
    const reverseList = head => {
        let cur = head;
        let pre = null;
        while(cur !== null){
            let temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
    //Split linked list
    const spliceList = head => {
        let dummy = new ListNode(0);
            dummy.next = head;

        let slow = dummy;
        let quick = dummy;

        while (quick && quick.next) {
            slow = slow.next;
            quick = quick.next;
            quick = quick.next;
        }

        let right = slow.next;
            slow.next = null;
        let left = dummy.next;

        return {
            left,
            right,
            dummy
        }
    }

    let { left, right, dummy } = spliceList(head);

    right = reverseList(right);

    while (left && right) {
        let lNext = left.next;
        let rNext = right.next;
        right.next = left.next;
        left.next = right;
        left = lNext;
        right = rNext;
    }

    return dummy.next
};
Scheme II:
/*
 * @lc app=leetcode.cn id=143 lang=javascript
 *
 *[143] rearrange linked list
 */

// @lc code=start
/**
 * 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) {
  let list = []; //  Use arrays to store linked lists
  let node = head; //  Use node to traverse the linked list

  //Traverse the linked list and store each element in the array in turn
  while (node) {
    list.push(node);
    node = node.next;
  }

  let i = 0; //  Use the I pointer to traverse the list from beginning to end
  let j = list. length - 1; //  Use the j pointer to traverse the list from back to front

  //The two pointers push towards the middle until they meet
  while (i < j) {
    //Point I to j and move I back one bit
    list[i++].next = list[j];
    //Point J to I and move J forward one bit
    list[j--].next = list[i];
  }
  // list[i]. Next needs to be set to null, otherwise the linked list will become a ring
  list[i].next = null;

  //Head is also the head node of the new linked list
  return head;
};

There are two schemes: 1. The fast and slow pointer divides the left and right linked lists, and uses the insertion of the left and right linked lists to synthesize a new linked list; 2. Merge using the position of the array


2021.05.11

No.148 sorting linked list

Give you the head node of the linked list , head, please arrange it in ascending order and return the sorted linked list.
Advanced:

Can you sort the linked list under O (n log n) time complexity and constant space complexity?
 

Example 1:
Front end common algorithm questions (linked list)

Input: head = [4,2,1,3]
Output: [1,2,3,4]
Example 2:
Front end common algorithm questions (linked list)

Input: head = [- 1,5,3,4,0]
Output: [- 1,0,3,4,5]
Example 3:

Input: head = []
Output: []
 

Tips:

The number of nodes in the linked list is in the range [0, 5 * 104]
-105 <= Node.val <= 105

Source: leetcode
Link:https://leetcode-cn.com/problems/sort-list
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=148 lang=javascript
 *
 *[148] list sorting
 */

// @lc code=start
/**
 * 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 sortList = function(head) {
    //Linked list to array
    const  list2Arr = head => {
        if(!head) return [];
        const a = [head.val];
        while(head.next) {a.push(head.next.val);head = head.next;}
        return a;
    }
    //Array to linked list
    const arr2List = arr => {
        if(arr.length == 0) return null;
        let head = new ListNode(arr[0]);
        let cur = head;
        for(let i=1; i < arr.length; i++) {
            cur.next = new ListNode(arr[i]);
            cur = cur.next;
        };
        return head;
    };
    //Reorder arrays
    const sortArr = arr => {
        return arr.sort((a,b) => a-b)
    }

    return arr2List(sortArr(list2Arr(head)))
};
Scheme II:
/*
 * @lc app=leetcode.cn id=148 lang=javascript
 *
 *[148] list sorting
 */

// @lc code=start
/**
 * 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 sortList = function(head) {
    if (!head || !head.next)  return head;
    let slow = head, fast = head;
    let preSlow = null;
    while (fast && fast.next) {
        preSlow = slow;
        slow = slow.next;
        fast = fast.next.next;
    }
    preSlow.next = null;
    const l = sortList(head);
    const r = sortList(slow);
    //Merge linked list function
    const merge = (l1, l2) => {
        const dummy = new ListNode(0);
        let prev = dummy;
        while (l1 && l2) {
            if (l1.val < l2.val) {
                prev.next = l1;
                l1 = l1.next;
            } else {
                prev.next = l2;
                l2 = l2.next;
            }
            prev = prev.next;
        }
        if (l1) prev.next = l1;
        if (l2) prev.next = l2;
        return dummy.next;
    };
    return merge(l, r);
};

There are two schemes: 1. Array operation, using its own sort sorting; 2. Merge sort, fast and slow pointer implementation


2021.05.12

No.234 palindrome linked list

Please judge whether a linked list is a palindrome linked list. ​
Example 1:

Input: 1 – > 2
Output: false
Example 2:

Input: 1 – > 2 – > 2 – > 1
Output: true
Advanced:
Can you solve this problem with O (n) time complexity and O (1) space complexity?

Source: leetcode
Link:https://leetcode-cn.com/problems/palindrome-linked-list
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme I:
/*
 * @lc app=leetcode.cn id=234 lang=javascript
 *
 *[234] palindrome linked list
 */

// @lc code=start
/**
 * 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 {boolean}
 */
var isPalindrome = function(head) {
    //Flip linked list
    const reverseList = head => {
        let cur=head;
        let pre=null;
        while(cur !== null){
            let temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
    }

    //Split linked list
    const splitList = head => {
        let fast = head;
        let slow = head;
        while (fast.next !== null && fast.next.next !== null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

    if (head == null) return true;

    let l = head; 
    let _l = reverseList(splitList(head).next);

    while( l !== null && _l !== null ) {
        if(l.val !== _l.val) {
            return false;
        }
        l = l.next;
        _l = _l.next;
    }

    return true;
};
Scheme II:
/*
 * @lc app=leetcode.cn id=234 lang=javascript
 *
 *[234] palindrome linked list
 */

// @lc code=start
/**
 * 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 {boolean}
 */
var isPalindrome = function(head) {
    let a='',b='';
    while(head!=null){
        a=a+head.val;
        b=head.val+b;
        head=head.next;
    }
  return a===b;
};
Scheme III:
/*
 * @lc app=leetcode.cn id=234 lang=javascript
 *
 *[234] palindrome linked list
 */

// @lc code=start
/**
 * 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 {boolean}
 */
var isPalindrome = function(head) {
    const vals = [];
    while (head !== null) {
        vals.push(head.val);
        head = head.next;
    }
    for (let i = 0, j = vals.length - 1; i < j; ++i, --j) {
        if (vals[i] !== vals[j]) {
            return false;
        }
    }
    return true;
};

There are three schemes: 1. Use the fast and slow pointer to get the second half of the linked list for flipping comparison; 2. Using the plus sign feature of JS, a stack like operation is realized; 3. Comparison of flipped arrays using arrays


2021.05.13

No.328 parity linked list

Given a single linked list, all odd nodes and even nodes are arranged together respectively. Note that the odd and even nodes here refer to the parity of node numbers, not the parity of node values. ​
Try using the in place algorithm. The space complexity of your algorithm should be o (1), the time complexity should be o (nodes), and nodes is the total number of nodes.

Example 1:

Input: 1 – > 2 – > 3 – > 4 – > 5 – > null
Output: 1 – > 3 – > 5 – > 2 – > 4 – > null
Example 2:

Input: 2 – > 1 – > 3 – > 5 – > 6 – > 4 – > 7 – > null
Output: 2 – > 3 – > 6 – > 7 – > 1 – > 5 – > 4 – > null
explain:

The relative order of odd and even nodes should be maintained.
The first node of the linked list is regarded as an odd node, the second node is regarded as an even node, and so on.

Source: leetcode
Link:https://leetcode-cn.com/problems/odd-even-linked-list
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Scheme:
/*
 * @lc app=leetcode.cn id=328 lang=javascript
 *
 *[328] parity linked list
 */

// @lc code=start
/**
 * 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 oddEvenList = function(head) {
    if(!head) return null;

    let p = head,
        q = head.next,
        tmp = q;
    
    while(q && q.next) {
        p.next = p.next.next;
        q.next = q.next.next;
        p = p.next;
        q = q.next;
    }

    p.next = tmp;

    return head;
};

Using double pointers for segmentation


Summary:
  1. The most common scheme of special linked list is to search and process the related linked list with fast and slow pointers, and then split and combine according to the form requirements of special linked list;
  2. Additional data structures such as stack and hash table can also be used for processing

Front end common algorithm questions (linked list)

Recommended Today

JS generate guid method

JS generate guid method https://blog.csdn.net/Alive_tree/article/details/87942348 Globally unique identification(GUID) is an algorithm generatedBinaryCount Reg128 bitsNumber ofidentifier , GUID is mainly used in networks or systems with multiple nodes and computers. Ideally, any computational geometry computer cluster will not generate two identical guids, and the total number of guids is2^128In theory, it is difficult to make two […]