origin

At present, algorithm questions are almost required in dafa interviews, and LeetCode real questions frequently appear in recent years. This article is for the author who got the Offer from Byte, Tencent and JD, and I have personally brush and encountered high-frequency algorithm questions in the process of preparing for the interview. Article content will be divided into modules, for the author encountered in the interview process, will give emphasis to [🔥] marked.

At the same time, it’s easy to say that if you have limited time to prepare and want to maximize the efficiency of algorithmic preparation, then you only need to brush the following questions according to the outline, and know the code by heart, almost 90% of the interview algorithmic questions can be dealt with.

The purpose of sorting out this content is a little accumulation of the author in the preparation of the interview before, and it does also help the author in the interview algorithm to overcome, at the same time, also hope to be able to give hard work in the gold three silver four you, a little help! 💪

Benefits at the end 🙂 😈

This section includes the following modules:

  • High frequency algorithm series: linked list
  • 【🔥】【 have true 题】 high frequency algorithm 题 series: string
  • 【🔥】【 there is true 题】 high frequency algorithm 题 series: array problem
  • High frequency algorithm series: binary tree
  • 【🔥】 High frequency algorithm series: sorting algorithm
  • 【🔥】 High frequency algorithm series: binary search
  • 【🔥】 High frequency algorithm series: dynamic programming
  • High frequency algorithm series: BFS
  • 【🔥】 High frequency algorithm series: stack
  • 【🔥】 High frequency algorithm series: DFS
  • 【🔥】 High frequency algorithm series: backtracking algorithm

The part of its bid 🔥 represents very high frequency examination questions, including some of the original questions encountered by the author. One for each category, the first list contains questions, and then for each exam will give difficulty, study knowledge, whether the interview bo, in each of the problem in detail, will give each question LeetCode link, to help readers to understand the question, as well as to the actual test, can watch other people’s answers, better help.

High frequency algorithm series: linked list

The high-frequency linked list questions I encountered mainly include the following:

  • Judging palindromic linked list problem by the subsequent traversal of the linked list
  • The reverse output of the linked list
  • Merge K ascending linked lists
  • A set of K to flip a linked list
  • Ring linked list
  • Sorted list [medium]
  • Intersection linked list

Preorder traversal to judge palindrome linked list

👉 [LeetCode] : 234 Palindrome Linked List

Answer key 1

Using the following traversal of the linked list, using the function call stack as the post-order traversal stack to judge whether palindrome

→ Click to expand view

/ * * * * /
var isPalindrome = function(head) {
    let left = head;
    function traverse(right) {
        if (right == null) return true;
        let res = traverse(right.next);
        res = res && (right.val === left.val);
        left = left.next;
        return res;
    }
    return traverse(head);
};

Copy the code

Answer key 2

Through the fast and slow pointer to find the middle point of the list, and then reverse the list, compare the two sides of the list is equal, to determine whether it is palindrome list

→ Click to expand view

/ * * * * /
var isPalindrome = function(head) {
    // Reverse slower list
    let right = reverse(findCenter(head));
    let left = head;
    // Start the comparison
    while(right ! =null) {
        if(left.val ! == right.val) {return false;
        }
        left = left.next;
        right = right.next;
    }
    return true;
}
function findCenter(head) {
    let slower = head, faster = head;
    while(faster && faster.next ! =null) {
        slower = slower.next;
        faster = faster.next.next;
    }
    // If faster does not equal null, an odd number and move one more cell
    if(faster ! =null) {
        slower = slower.next;
    }
    return slower;
}
function reverse(head) {
    let prev = null, cur = head, nxt = head;
    while(cur ! =null) {
        nxt = cur.next;
        cur.next = prev;
        prev = cur;
        cur = nxt;
    }
    return prev;
}

Copy the code

Reverse a linked list

👉 [LeetCode] : 206 Reverse Linked List (simple)

Answer key

→ Click to expand view

/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; *} * /
/ * * *@param {ListNode} head
 * @return {ListNode}* /
var reverseList = function(head) {
    if (head == null || head.next == null) return head;
    let last = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return last;
};

Copy the code

Merge K ascending linked lists

👉 [LeetCode] : 23 merge K ascending lists (difficult)

Answer key

→ Click to expand view

/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; *} * /
/ * * *@param {ListNode[]} lists
 * @return {ListNode}* /
var mergeKLists = function(lists) {
    if (lists.length === 0) return null;
    return mergeArr(lists);
};
function mergeArr(lists) {
    if (lists.length <= 1) return lists[0];
    let index = Math.floor(lists.length / 2);
    const left = mergeArr(lists.slice(0, index))
    const right = mergeArr(lists.slice(index));
    return merge(left, right);
}
function merge(l1, l2) {
    if (l1 == null && l2 == null) return null;
    if(l1 ! =null && l2 == null) return l1;
    if (l1 == null&& l2 ! =null) return l2;
    let newHead = null, head = null;
    while(l1 ! =null&& l2 ! =null) {
        if (l1.val < l2.val) {
            if(! head) { newHead = l1; head = l1; }else {
                newHead.next = l1;
                newHead = newHead.next;
            }
            l1 = l1.next;
        } else {
            if(! head) { newHead = l2; head = l2; }else {
                newHead.next = l2;
                newHead = newHead.next;
            }
            l2 = l2.next;
        }
    }
    newHead.next = l1 ? l1 : l2;
    return head;
}

Copy the code

K sets of reverse lists

👉 [LeetCode express] : a set of 25 K overturn lists (difficult)

Answer key

→ Click to expand view

/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; *} * /
/ * * *@param {ListNode} head
 * @param {number} k
 * @return {ListNode}* /
var reverseKGroup = function(head, k) {
    let a = head, b = head;
    for (let i = 0; i < k; i++) {
        if (b == null) return head;
        b = b.next;
    }
    const newHead = reverse(a, b);
    a.next = reverseKGroup(b, k);
    return newHead;
};
function reverse(a, b) {
    let prev = null, cur = a, nxt = a;
    while(cur ! = b) { nxt = cur.next; cur.next = prev; prev = cur; cur = nxt; }return prev;
}

Copy the code

Circular linked list

👉 [LeetCode express] : 141 Ring Linked List

Answer key

→ Click to expand view

/** * 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 == null || head.next == null) return false;
    let slower = head, faster = head;
    while(faster ! =null&& faster.next ! =null) {
        slower = slower.next;
        faster = faster.next.next;
        if (slower === faster) return true;
    }
    return false;
};

Copy the code

Sorting list

👉 [LeetCode express] : 148 Sorted List (medium)

Answer key

→ Click to expand view

/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; *} * /
/ * * *@param {ListNode} head
 * @return {ListNode}* /
var sortList = function(head) {
    if (head == null) return null;
    let newHead = head;
    return mergeSort(head);
};
function mergeSort(head) {
    if(head.next ! =null) {
        let slower = getCenter(head);
        let nxt = slower.next;
        slower.next = null;
        console.log(head, slower, nxt);
        const left = mergeSort(head);
        const right = mergeSort(nxt);
        head = merge(left, right);
    }
    return head;
}
function merge(left, right) {
    let newHead = null, head = null;
    while(left ! =null&& right ! =null) {
        if (left.val < right.val) {
            if(! head) { newHead = left; head = left; }else {
                newHead.next = left;
                newHead = newHead.next;
            }
            left = left.next;
        } else {
            if(! head) { newHead = right; head = right; }else {
                newHead.next = right;
                newHead = newHead.next;
            }
            right = right.next;
        }
    }
    newHead.next = left ? left : right;
    return head;
}
function getCenter(head) {
    let slower = head, faster = head.next;
    while(faster ! =null&& faster.next ! =null) {
        slower = slower.next;
        faster = faster.next.next;
    }
    return slower;
}

Copy the code

Cross linked list

👉 [LeetCode express] : 160 Intersection list (simple)

Answer key

→ Click to expand view

/** * 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 lastHeadA = null;
    let lastHeadB = null;
    let originHeadA = headA;
    let originHeadB = headB;
    if(! headA || ! headB) {return null;
    }
    while (true) {
        if (headB == headA) {
            return headB;
        }
        if (headA && headA.next == null) {
            lastHeadA = headA;
            headA = originHeadB;
        } else {
            headA = headA.next;
        }
        if (headB && headB.next == null) {
            lastHeadB = headB
            headB = originHeadA;
        } else {
            headB = headB.next;
        }
        if(lastHeadA && lastHeadB && lastHeadA ! = lastHeadB) {return null; }}return null;
};

Copy the code

【🔥】 High frequency algorithm series: string

There are mainly the following high-frequency questions:

  • 【 答 案 】【 答 案 】【 答 案 】【 答 案 】【 答 案 】
  • Longest common prefix [simple] [double pointer]
  • The oldest string without repeating characters [medium] [double pointer]
  • 【 difficulty 】【 sliding window 】【 interview 真题】

【 答 案 】 【 答 案 】 【 答 案 】 【 答 案 】

👉 [LeetCode express] : 5

Answer key

→ Click to expand view

/ * * *@param {string} s
 * @return {string}* /
var longestPalindrome = function(s) {
    if (s.length === 1) return s;
    let maxRes = 0, maxStr = ' ';
    for (let i = 0; i < s.length; i++) {
        let str1 = palindrome(s, i, i);
        let str2 = palindrome(s, i, i + 1);   
        if (str1.length > maxRes) {
            maxStr = str1;
            maxRes = str1.length;
        }
        if(str2.length > maxRes) { maxStr = str2; maxRes = str2.length; }}return maxStr;
};
function palindrome(s, l, r) {
    while (l >= 0 && r < s.length && s[l] === s[r]) {
        l--;
        r++;
    }
    return s.slice(l + 1, r);
}

Copy the code

Longest common prefix [double pointer]

👉 [LeetCode express] : 14 longest common prefix (simple)

Answer key

→ Click to expand view

/ * * *@param {string[]} strs
 * @return {string}* /
var longestCommonPrefix = function(strs) {
    if (strs.length === 0) return "";
    let first = strs[0];
    if (first === "") return "";
    let minLen = Number.MAX_SAFE_INTEGER;
    for (let i = 1; i < strs.length; i++) {
        const len = twoStrLongestCommonPrefix(first, strs[i]);
        minLen = Math.min(len, minLen);
    }
    return first.slice(0, minLen);
};
function twoStrLongestCommonPrefix (s, t) {
    let i = 0, j = 0;
    let cnt = 0;
    while (i < s.length && j < t.length) {
        console.log(s[i], t[j], cnt)
        if (s[i] === t[j])  {
            cnt++;
        } else {
            return cnt;
        }
        i++;
        j++;
    }
    return cnt;
}

Copy the code

The oldest string with no duplicate characters [double pointer]

👉 [LeetCode] : 3 Maximum string without duplicate characters (medium)

Answer key

→ Click to expand view

/ * * *@param {string} s
 * @return {number}* /
var lengthOfLongestSubstring = function(s) {
  let window = {};
  let left = 0, right = 0;
  let maxLen = 0, maxStr = ' ';
  while (right < s.length) {
    let c = s[right];
    right++;
    if (window[c]) window[c]++;
    else window[c] = 1
    while (window[c] > 1) {
      let d = s[left];
      left++;
      window[d]--;
    }
    if(maxLen < right - left) { maxLen = right - left; }}return maxLen;
};

Copy the code

Minimum coverage substring [Sliding window]

👉 [LeetCode express] : 76 minimum coverage substring (difficult)

Answer key

→ Click to expand view

/ * * *@param {string} s
 * @param {string} t
 * @return {string}* /
var minWindow = function(s, t) {
    let need = {}, window = {};
    for (let c of t) {
        if(! need[c]) need[c] =1;
        else need[c]++;
    }
    let left = 0, right = 0;
    let valid = 0, len = Object.keys(need).length;
    let minLen = s.length + 1, minStr = ' ';
    while (right < s.length) {
        const d = s[right];
        right++;
        if (!window[d]) window[d] = 1;
        else window[d]++;
        if (need[d] && need[d] === window[d]) {
            valid++;
        }
        console.log('left - right', left, right);
        while (valid === len) {
            if (right - left < minLen) {
                minLen = right - left;
                minStr = s.slice(left, right);
            }
            console.lo
            let c = s[left];
            left++;
            window[c]--;
            if (need[c] && window[c] < need[c]) { valid--; }}}return minStr;
};

Copy the code

【🔥】 High frequency algorithm series: array problem

There are several types of high-frequency exam questions:

  • Russian doll envelope problem [difficult] [sort + longest rising sub-sequence] [interview true question]
  • Longest continuously increasing sequence [simple] [double pointer]
  • Longest continuous sequence [difficulty] [hash table]
  • The container that holds the most water
  • Finding the median of two ordinal sets [difficulty] [double pointer]
  • Delete duplicates from an ordered array
  • And a subarray of K
  • NSum problem [series] [simple] [hash table]
  • 【 答 案 】【 答 案 】【 答 案 】【 答 案 】【 答 案 】【 答 案 】
  • Jumping Game [Series] [Medium] [Greedy Algorithm]

[Interview true question] Russian nesting doll envelope problem [sort + longest ascending child sequence]

👉 [LeetCode direct train] : 354 Russian nesting doll envelope problem (difficulty)

Answer key

→ Click to expand view

/ * * *@param {number[][]} envelopes
 * @return {number}* /
var maxEnvelopes = function(envelopes) {
  if (envelopes.length === 1) return 1;
    envelopes.sort((a, b) = > {
        if (a[0] !== b[0]) return a[0] - b[0];
        else return b[1] - a[1];
    });
    let LISArr = [];
    for (let [key, value] of envelopes) {
      LISArr.push(value);
    }
    console.log( LISArr);
    return LIS(LISArr);
};
function LIS(arr) {
  let dp = [];
  let maxAns = 0;
  for (let i = 0; i < arr.length; i++) {
    dp[i] = 1;
  }
  for (let i = 1; i < arr.length; i++) {
    for (let j = i; j >= 0; j--) {
      if (arr[i] > arr[j]) {
        dp[i] = Math.max(dp[i], dp[j] + 1)
      }
      maxAns = Math.max(maxAns, dp[i]); }}return maxAns;
}

Copy the code

Longest continuously increasing sequence [fast pointer]

👉 [LeetCode express] : 674 Longest continuously increasing sequence (simple)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @return {number}* /
var findLengthOfLCIS = function(nums) {
    if (nums.length === 0) return 0;
    const n = nums.length;
    let left = 0, right = 1;
    let globalMaxLen = 1, maxLen = 1;
    while (right < n) {
        if (nums[right] > nums[left]) maxLen++;
        else {
            maxLen = 1;
        }
        left++;
        right++;
        globalMaxLen = Math.max(globalMaxLen, maxLen);
    }
    return globalMaxLen;
};

Copy the code

Longest continuous sequence [hash table]

👉 [LeetCode express] : 128 longest continuous sequence (difficult)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @return {number}* /
var longestConsecutive = function(nums) {
    if (nums.length === 0) return 0;
    const set = new Set(nums);
    const n = nums.length;
    let globalLongest = 1;
    for (let i = 0; i < n; i++) {
        if(! set.has(nums[i] -1)) {
            let longest = 1;
            let currentNum = nums[i];
            while (set.has(currentNum + 1)) {
                currentNum += 1;
                longest++;
            }
            globalLongest = Math.max(globalLongest, longest); }}return globalLongest;
};

Copy the code

【 hash table 】 The container that holds the most water

👉 [LeetCode express] : 11 Containers with the most water (medium)

Answer key

→ Click to expand view

/ * * *@param {number[]} height
 * @return {number}* /
var maxArea = function(height) {
    let n = height.length;
    let left = 0, right = n - 1;
    let maxOpacity = 0;
    while (left < right) {
        let res = Math.min(height[left], height[right]) * (right - left);
        maxOpacity = Math.max(maxOpacity, res);
        if (height[left] < height[right]) left++
        else right--;
    }
    return maxOpacity;
};

Copy the code

Find the median of two ordinal sets

👉 [LeetCode] : 4 Finding the median of two ordinal groups (difficult)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}* /
var findMedianSortedArrays = function(nums1, nums2) {
    let m = nums1.length, n = nums2.length;
    let i = 0, j = 0;
    let newArr = [];
    while (i < m && j < n) {
        if (nums1[i] < nums2[j]) {
            newArr.push(nums1[i++]);
        } else {
            newArr.push(nums2[j++]);
        }
    }
    newArr = newArr.concat(i < m ? nums1.slice(i) : nums2.slice(j));
    const len = newArr.length;
    console.log(newArr)
    if (len % 2= = =0) {
        return (newArr[len / 2] + newArr[len / 2 - 1) /2;
    } else {
        return newArr[Math.floor(len / 2)]; }};Copy the code

Remove duplicates from an ordered array

👉 [LeetCode] : 26 Remove duplicates from ordered arrays

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @return {number}* /
var removeDuplicates = function(nums) {
  if (nums.length <= 1) return nums.length;
  let lo = 0, hi = 0;
  while (hi < nums.length) {
    while (nums[lo] === nums[hi] && hi < nums.length) hi++;
    if(nums[lo] ! == nums[hi] && hi < nums.length) { lo++; nums[lo] = nums[hi]; } hi++; }return lo + 1;
};

Copy the code

And a subarray of K

👉 [LeetCode express] : 560 and subarray of K (medium)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @param {number} k
 * @return {number}* /
var subarraySum = function(nums, k) {
    let cnt = 0;
    let sum0_i = 0, sum0_j = 0;
    let map = new Map(a); map.set(0.1);
    for (let i = 0; i <= nums.length; i++) {
        sum0_i += nums[i];
        sum0_j = sum0_i - k;
        console.log('map', sum0_j, map.get(sum0_j))
        if (map.has(sum0_j)) {
            cnt += map.get(sum0_j);
        }
        let sumCnt = map.get(sum0_i) || 0;
        map.set(sum0_i, sumCnt + 1);
    }
    return cnt;
};

Copy the code

NSum problem hash table series

  • 👉 : 1 The sum of two numbers (simple)
  • 👉 [LeetCode] : 167 Sum of two numbers II – Input ordered array (simple)
  • 👉 [LeetCode express] : 15 The sum of three numbers (medium)
  • 👉 [LeetCode] : 18 The sum of four numbers (medium)

Limited by space, only the code template for the first question is given here, which is also a common test of the real question.

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @param {number} target
 * @return {number[]}* /
var twoSum = function(nums, target) {
  let map2 = new Map(a);for (let i = 0; i < nums.length; i++) {
    map2.set(nums[i], i);
  }
  for (let i = 0; i < nums.length; i++) {
    if(map2.has(target - nums[i]) && map2.get(target - nums[i]) ! == i)return [i, map2.get(target - nums[i])]
  }
};

Copy the code

【 答 案 】 Catch rain 【 violence + memo optimization 】

👉 [LeetCode express] : 42 Catch rain (difficult)

Answer key

→ Click to expand view

/ * * *@param {number[]} height
 * @return {number}* /
var trap = function(height) {
    let l_max = [], r_max = [];
    let len = height.length;
    let maxCapacity = 0;
    for (let i = 0; i < len; i++) {
        l_max[i] = height[i];
        r_max[i] = height[i];
    }
    for (let i = 1; i < len; i++) {
        l_max[i] = Math.max(l_max[i - 1], height[i]);
    }
    for (let j = len - 2; j >= 0; j--) {
        r_max[j] = Math.max(r_max[j + 1], height[j]);
    }
    for (let i = 0; i < len; i++) {
        maxCapacity += Math.min(l_max[i], r_max[i]) - height[i];
    }
    return maxCapacity;
};

Copy the code

Jumping Game [Greedy Algorithm] [Series]

  • 👉 [LeetCode express] : 55 Jump games (medium)
  • 👉 [LeetCode Express] : 45 Jump Game II (medium)

Limited by space, only the code template for the first question is given here, which is also a common test of the real question.

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @return {boolean}* /
var canJump = function(nums) {
    let faster = 0;
    for (let i = 0; i < nums.length - 1; i++) {
        faster = Math.max(faster, i + nums[i]);
        if (faster <= i) return false;
    }
    return faster >= nums.length - 1;
};

Copy the code

High frequency algorithm series: binary tree

There are mainly the following high-frequency questions:

  • The most recent common ancestor of a binary tree
  • Binary search tree search [simple] [binary tree]
  • Delete nodes in binary search tree [medium] [binary tree]
  • Number of nodes in a complete binary tree [medium]
  • Serrated sequence traversal of binary trees [medium] [Binary tree]

The most recent common ancestor of a binary tree

👉 [LeetCode express] : most recent common ancestor of 236 binary trees (simple)

Answer key

→ Click to expand view

/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; *} * /
/ * * *@param {TreeNode} root
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {TreeNode}* /
let visited;let parent;
var lowestCommonAncestor = function(root, p, q) {
    visited = new Set(a); parent =new Map(a); dfs(root);while(p ! =null) {
        visited.add(p.val);
        p = parent.get(p.val);
    }
    while(q ! =null) {
        if (visited.has(q.val)) {
            return q;
        }
        q = parent.get(q.val);
    }
    return null;
};
function dfs(root) {
    if(root.left ! =null) {
        parent.set(root.left.val, root);
        dfs(root.left);
    }
    if(root.right ! =null) { parent.set(root.right.val, root); dfs(root.right); }}Copy the code

Search in a binary search tree

👉 [LeetCode express] : 700 binary search tree search (simple)

Answer key

→ Click to expand view

/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; *} * /
/ * * *@param {TreeNode} root
 * @param {number} val
 * @return {TreeNode}* /
var searchBST = function(root, val) {
    if (root == null) return null;
    if (root.val === val) return root;
    if (root.val > val) {
        return searchBST(root.left, val);
    } else if (root.val < val) {
        returnsearchBST(root.right, val); }};Copy the code

Delete a node from a binary search tree

👉 : 450 Delete node in binary search tree (medium)

Answer key

→ Click to expand view

/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; *} * /
/ * * *@param {TreeNode} root
 * @param {number} key
 * @return {TreeNode}* /
var deleteNode = function(root, key) {
    if (root == null) return null;
    if (root.val === key) {
        if (root.left == null && root.right == null) return null;
        if (root.left == null) return root.right;
        if (root.right == null) return root.left;
        if(root.left ! =null&& root.right ! =null)  {
            lettarget = getMinTreeMaxNode(root.left); root.val = target.val; root.left = deleteNode(root.left, target.val); }}if (root.val < key) {
        root.right = deleteNode(root.right, key);
    } else if (root.val > key) {
        root.left = deleteNode(root.left, key);
    }
    return root;
};
function getMinTreeMaxNode(root) {
    if (root.right == null) return root;
    return getMinTreeMaxNode(root.right);
}

Copy the code

Number of nodes in a complete binary tree

👉 [LeetCode] : 222 Number of nodes in a complete binary tree (medium)

Answer key

→ Click to expand view

/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; *} * /
/ * * *@param {TreeNode} root
 * @return {number}* /
var countNodes = function(root) {
    if (root == null) return 0;
    let l = root, r = root;
    let lh = 0, rh = 0;
    while(l ! =null) {
      l = l.left;
      lh++;
    }
    while(r ! =null) {
      r = r.right;
      rh++;
    }
    if (lh === rh) {
      return Math.pow(2, lh) - 1;
    }
    return 1 + countNodes(root.left) + countNodes(root.right);
};

Copy the code

Zigzag sequence traversal of binary trees

👉 [LeetCode express] : 103 Serrated sequence Traversal of binary trees (medium)

Answer key

→ Click to expand view

/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; *} * /
/ * * *@param {TreeNode} root
 * @return {number[][]}* /
let res;
var zigzagLevelOrder = function(root) {
    if (root == null) return [];
    res = [];
    BFS(root, true);
    return res;
};
function BFS(root, inOrder) {
    let arr = [];
    let resItem = [];
    let node;
    let stack1 = new Stack();
    let stack2 = new Stack();
    // Determine the timing of the exchange
    letflag; stack1.push(root); res.push([root.val]); inOrder = ! inOrder;while(! stack1.isEmpty() || ! stack2.isEmpty()) {if (stack1.isEmpty()) {
            flag = 'stack1';
        } else if (stack2.isEmpty()) {
            flag = 'stack2';
        }
        // Decide which stack element to take
        if (flag === 'stack2' && !stack1.isEmpty()) node = stack1.pop();
        else if (flag === 'stack1' && !stack2.isEmpty()) node = stack2.pop();
        if (inOrder) {
            if (node.left) {
                if (flag === 'stack1') {
                    stack1.push(node.left);
                } else {
                    stack2.push(node.left);
                }
                resItem.push(node.left.val);
            }
            if (node.right) {
                if (flag === 'stack1') {
                    stack1.push(node.right);
                } else{ stack2.push(node.right); } resItem.push(node.right.val); }}else {
            if (node.right) {
                if (flag === 'stack1') {
                    stack1.push(node.right);
                } else {
                    stack2.push(node.right);
                }
                resItem.push(node.right.val);
            }
            if (node.left) {
                if (flag === 'stack1') {
                    stack1.push(node.left);
                } else{ stack2.push(node.left); } resItem.push(node.left.val); }}// Determine the time of the next flip
        if ((flag === 'stack2' && stack1.isEmpty()) || (flag === 'stack1'&& stack2.isEmpty())) { inOrder = ! inOrder;// If you need to flip, add one rotation
            if (resItem.length > 0) { res.push(resItem); } resItem = []; }}}class Stack {
    constructor() {
        this.count = 0;
        this.items = [];
    }
    push(element) {
        this.items[this.count] = element;
        this.count++;
    }
    pop() {
        if (this.isEmpty()) return undefined;
        const element = this.items[this.count - 1];
        delete this.items[this.count - 1];
        this.count--;
        return element;
    }
    size() {
        return this.count;
    }
    isEmpty() {
        return this.size() === 0; }}Copy the code

【🔥】 High frequency algorithm series: sorting algorithm

There are mainly the following high-frequency questions:

  • Explode a balloon with the least number of arrows [medium] [Sort]
  • Merge interval [medium] [sorting algorithm + interval problem] [interview true question]

Explode the balloon with the least number of arrows.

👉 [LeetCode Express] : 452 Explode balloon with minimum number of arrows (medium)

Answer key

→ Click to expand view

/ * * *@param {number[][]} points
 * @return {number}* /
var findMinArrowShots = function(points) {
    if (points.length === 0) return 0;
    points.sort((a, b) = > a[1] - b[1]);
    let cnt = 1;
    let resArr = [points[0]].let curr, last;
    for (let i = 1; i < points.length; i++) {
        curr = points[i];
        last = resArr[resArr.length - 1];
        if (curr[0] > last[1]) { resArr.push(curr); cnt++; }}return cnt;
};

Copy the code

Merge interval [sorting algorithm + interval problem]

👉 [LeetCode express] : 56 Merge interval (medium)

Answer key

→ Click to expand view

/ * * *@param {number[][]} intervals
 * @return {number[][]}* /
var merge = function(intervals) {
    if (intervals.length === 0) return [];
    intervals.sort((a, b) = > a[0] - b[0]);
    let mergeArr = [intervals[0]].let last, curr;
    for (let j = 1; j < intervals.length; j++) {
        last = mergeArr[mergeArr.length - 1];
        curr = intervals[j];
        if (last[1] >= curr[0]) {
            last[1] = Math.max(curr[1], last[1]);
        } else{ mergeArr.push(curr); }}return mergeArr;
};

Copy the code

High frequency algorithm series: binary search

There are mainly the following high-frequency questions:

  • Finding the median of two ordinal groups
  • Judge subsequence [simple] [binary search]
  • Find the first and last position of an element in a sorted array [medium] [Binary search]

Find the median of two ordinal groups

👉 [LeetCode] : 4 Finding the median of two ordinal groups (difficult)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}* /
var findMedianSortedArrays = function(nums1, nums2) {
    let m = nums1.length, n = nums2.length;
    let i = 0, j = 0;
    let newArr = [];
    while (i < m && j < n) {
        if (nums1[i] < nums2[j]) {
            newArr.push(nums1[i++]);
        } else {
            newArr.push(nums2[j++]);
        }
    }
    newArr = newArr.concat(i < m ? nums1.slice(i) : nums2.slice(j));
    const len = newArr.length;
    console.log(newArr)
    if (len % 2= = =0) {
        return (newArr[len / 2] + newArr[len / 2 - 1) /2;
    } else {
        return newArr[Math.floor(len / 2)]; }};Copy the code

Judge subsequence [binary search]

👉 [LeetCode express] : 392

Answer key

→ Click to expand view

/ * * *@param {string} s
 * @param {string} t
 * @return {boolean}* /
var isSubsequence = function(s, t) {
    let hash = {};
    for (let i = 0; i < t.length; i++) {
        if(! hash[t[i]]) hash[t[i]] = []; hash[t[i]].push(i); }let lastMaxIndex = 0;
    for (let i = 0; i < s.length; i++) {
        if (hash[s[i]]) {
            const index = binarySearch(hash[s[i]], lastMaxIndex);
            console.log('index', index, hash[s[i]]);
            if (index === -1) return false;
            lastMaxIndex = hash[s[i]][index] + 1;
        } else return false;
    }
    return true;
};
function binarySearch(array, targetIndex) {
    let left = 0, right = array.length;
    while (left < right) {
        let mid = left + Math.floor((right - left) / 2);
        if (array[mid] >= targetIndex) {
            right = mid;
        } else if (array[mid] < targetIndex) {
            left = mid + 1; }}if (left >= array.length || array[left] < targetIndex) return -1;
    return left;
}

Copy the code

💁 Find the first and last position of an element in a sorted array [binary search]

👉 [LeetCode] : 34 Find the first and last position of an element in a sorted array (medium)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @param {number} target
 * @return {number[]}* /
var searchRange = function(nums, target) {
    const left = leftBound(nums, target);
    const right = rightBound(nums, target);
    return [left, right];
};
function leftBound(nums, target) {
    let left = 0;
    let right = nums.length - 1;
    while (left <= right) {
        let mid = Math.floor(left + (right - left) / 2);
        if (nums[mid] === target) {
            right = mid - 1;
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1; }}if(left >= nums.length || nums[left] ! == target) {return -1;
    }
    return left;
}
function rightBound(nums, target) {
    let left = 0;
    let right = nums.length - 1;
    while (left <= right) {
        let mid = Math.floor(left + (right - left) / 2);
        if (nums[mid] === target) {
            left = mid + 1;
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1; }}if (right < 0|| nums[right] ! == target) {return -1;
    }
    return right;
}

Copy the code

【🔥】 High frequency algorithm series: dynamic programming

There are mainly the following high-frequency questions:

  • Longest increasing subsequence [medium] [Dynamic programming]
  • 【 medium 】【 dynamic programming 】【 interview 真题】
  • The longest common subsequence [medium] [Dynamic programming]
  • Edit distance [difficulty] [Dynamic programming]
  • 【 答 案 】【 答 案 】【 答 案 】【 答 案 】【 答 案 】【 答 案 】【 答 案 】
  • 【 simple 】【 dynamic programming 】【 interview 真题】
  • The best time to buy and sell stocks

Longest increasing subsequence [Dynamic programming]

👉 [LeetCode express] : 300 longest increasing subsequence (medium)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @return {number}* /
var lengthOfLIS = function(nums) {
    let maxLen = 0, n = nums.length;
    let dp = [];
    for (let i = 0; i < n; i++) {
        dp[i] = 1;
    }
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < i; j++) {
            if (nums[i] > nums[j]) {
                dp[i] = Math.max(dp[i], dp[j] + 1);
            }
        }
        maxLen = Math.max(maxLen, dp[i]);
    }
    return maxLen;
};

Copy the code

【 dynamic planning 】

👉 [LeetCode express] : 322 small change exchange (medium)

Answer key

→ Click to expand view

/ * * *@param {number[]} coins
 * @param {number} amount
 * @return {number}* /
var coinChange = function(coins, amount) {
  if (amount === 0) return 0;
  let dp = [];
  for (let i = 0; i <= amount; i++) {
    dp[i] = amount + 1;
  }
  dp[0] = 0;
  for (let i = 0; i <= amount; i++) {
    for (let j = 0; j < coins.length; j++) {
      if (i >= coins[j]) {
        dp[i] = Math.min(dp[i - coins[j]] + 1, dp[i])
      }
    }
  }
  return dp[amount] === amount + 1 ? -1 : dp[amount];
};

Copy the code

The longest common subsequence of dynamic programming

👉 [LeetCode express] : 1143 Longest common subsequence (medium)

Answer key

→ Click to expand view

/ * * *@param {string} text1
 * @param {string} text2
 * @return {number}* /
var longestCommonSubsequence = function(text1, text2) {
    let n1 = text1.length, n2 = text2.length;
    let dp = [];
    for (let i = -1; i < n1; i++) {
        dp[i] = [];
        for (let j = -1; j < n2; j++) { dp[i][j] =0; }}for (let i = 0; i < n1; i++) {
        for (let j = 0; j < n2; j++) {
            if (text1[i] === text2[j]) {
                dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + 1);
            } else {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1])}}}return dp[n1 - 1][n2 - 1];
};

Copy the code

Edit distance [Dynamic programming]

👉 [LeetCode express] : 72 edit distance (difficult)

Answer key

→ Click to expand view

/ * * *@param {string} word1
 * @param {string} word2
 * @return {number}* /
var minDistance = function(word1, word2) {
  let len1 = word1.length, len2 = word2.length;
  let dp = [];
  for (let i = 0; i <= len1; i++) {
    dp[i] = [];
    for (let j = 0; j <= len2; j++) {
      dp[i][j] = 0;
      if (i === 0) {
        dp[i][j] = j;
      }
      if (j === 0) { dp[i][j] = i; }}}for (let i = 1; i <= len1; i++) {
    for (let j = 1; j <= len2; j++) {
      if (word1[i - 1] === word2[j - 1]) {
        dp[i][j] = dp[i - 1][j - 1];
      } else {
        dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1); }}}return dp[len1][len2];
};

Copy the code

【 答 案 】 dynamic programming

👉 [LeetCode express] : 516

Answer key

→ Click to expand view

/ * * *@param {string} s
 * @return {number}* /
var longestPalindromeSubseq = function(s) {
    let dp = [];
    for (let i = 0; i < s.length; i++) {
        dp[i] = [];
        for (let j = 0; j < s.length; j++) {
            dp[i][j] = 0;
        }
        dp[i][i] = 1;
    }
    for (let i = s.length - 1; i >= 0; i--) {
        for (let j = i + 1; j < s.length; j++) {
            if (s[i] === s[j]) {
                dp[i][j] = dp[i + 1][j - 1] + 2;
            } else {
                dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]); }}}return dp[0][s.length - 1];
};

Copy the code

💁 maximum suborder and dynamic programming

👉 [LeetCode express] : 53 Max suborder sum (simple)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @return {number}* /
var maxSubArray = function(nums) {
    let maxSum = -Infinity;
    let dp = [], n = nums.length;
    for (let i = -1; i < n; i++) {
        dp[i] = 0;
    }
    for (let i = 0; i < n; i++) {
        dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);
        maxSum = Math.max(maxSum, dp[i]);
    }
    return maxSum;
};

Copy the code

💁 The best time to buy and sell stocks

  • 👉 [LeetCode express] : 121 The best time to buy and sell stocks
  • 👉 [LeetCode express] : 122 Best time to Buy and sell stocks II (Simple)
  • 👉 [LeetCode express] : 123 The best time to buy and sell stocks III (Difficulty)
  • 👉 [LeetCode] : 188 The best time to buy and sell stocks IV (Difficulty)
  • 👉 [LeetCode] : 309 The best time to buy and sell a stock includes the freeze period (medium)
  • 👉 [LeetCode Express] : 714 The best time to buy and sell stocks including fees (medium)

Due to the limited space, only the code template for the first question is given here, which is also one of the usual old exam questions, which the author encountered when interviewing bytedance.

Answer key

→ Click to expand view

/ * * *@param {number[]} prices
 * @return {number}* /
var maxProfit = function(prices) {
  let dp = [];
  for (let i = -1; i < prices.length; i++) {
    dp[i] = []
    for (let j = 0; j <= 1; j++) {
      dp[i][j] = [];
      dp[i][j][0] = 0;
      dp[i][j][1] = 0;
      if (i === -1) {
        dp[i][j][1] = -Infinity;
      }
      if (j === 0) {
        dp[i][j][1] = -Infinity;
      }
      if (j === -1) {
        dp[i][j][1] = -Infinity; }}}for (let i = 0; i < prices.length; i++) {
    for (let j = 1; j <= 1; j++) {
      dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
      dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1] [0] - prices[i]); }}return dp[prices.length - 1] [1] [0];
};

Copy the code

High frequency algorithm series: BFS

There are mainly the following high-frequency questions:

  • Open the turntable lock [medium] [BFS]
  • Minimum depth of binary tree

Open the turntable lock [BFS]

👉 [LeetCode express] : 752 Open the turntable lock (medium)

Answer key

→ Click to expand view

/ * * *@param {string[]} deadends
 * @param {string} target
 * @return {number}* /
var openLock = function(deadends, target) {
  let queue = new Queue();
  let visited = new Set(a);let step = 0;
  queue.push('0000');
  visited.add('0000');
  while(! queue.isEmpty()) {let size = queue.size();
    for (let i = 0; i < size; i++) {
      let str = queue.pop();
      if (deadends.includes(str)) continue;
      if (target === str) {
        return step;
      }
      for (let j = 0; j < 4; j++) {
        let plusStr = plusOne(str, j);
        let minusStr = minusOne(str, j);
        if(! visited.has(plusStr)) { queue.push(plusStr); visited.add(plusStr) }if(! visited.has(minusStr)) { queue.push(minusStr); visited.add(minusStr) } } } step++; }return -1;
};
function plusOne(str, index) {
  let strArr = str.split(' ');
  if (strArr[index] === '9') {
    strArr[index] = '0'
  } else {
    strArr[index] = (Number(strArr[index]) + 1).toString()
  }
  return strArr.join(' ');
}
function minusOne(str, index) {
  let strArr = str.split(' ');
  if (strArr[index] === '0') {
    strArr[index] = '9'
  } else {
    strArr[index] = (Number(strArr[index]) - 1).toString()
  }
  return strArr.join(' ');
}
class Queue {
  constructor() {
    this.items = [];
    this.count = 0;
    this.lowerCount = 0;
  }
  push(elem) {
    this.items[this.count++] = elem;
  }
  pop() {
    if (this.isEmpty()) {
      return;
    }
    const elem = this.items[this.lowerCount];
    delete this.items[this.lowerCount];
    this.lowerCount++;
    return elem;
  }
  isEmpty() {
    if (this.size() === 0) return true;
    return false;
  }
  size() {
    return this.count - this.lowerCount; }}Copy the code

Minimum depth of binary tree [BFS]

👉 [LeetCode] : 111 Minimum depth of binary tree

Answer key

→ Click to expand view

/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; *} * /
/ * * *@param {TreeNode} root
 * @return {number}* /
var minDepth = function(root) {
  if (root == null) return 0;
  let depth = 1;
  let queue = new Queue();
  queue.push(root);
  while(! queue.isEmpty()) {let size = queue.size();
    for (let i = 0; i < size; i++) {
      const node = queue.pop();
      if (node.left == null && node.right == null) return depth;
      if (node.left) {
        queue.push(node.left);
      }
      if (node.right) {
        queue.push(node.right);
      }
    }
    depth++;
  }
  return depth;
};
class Queue {
  constructor() {
    this.items = [];
    this.count = 0;
    this.lowerCount = 0;
  }
  push(elem) {
    this.items[this.count++] = elem;
  }
  pop() {
    if (this.isEmpty()) {
      return;
    }
    const elem = this.items[this.lowerCount];
    delete this.items[this.lowerCount];
    this.lowerCount++;
    return elem;
  }
  isEmpty() {
    if (this.size() === 0) return true;
    return false;
  }
  size() {
    return this.count - this.lowerCount; }}Copy the code

【🔥】 High frequency algorithm series: stack

There are mainly the following high-frequency questions:

  • Minimum stack [simple] [stack]
  • 【 答 案 】【 答 案 】【 答 案 】【 答 案 】
  • Simplified path [medium] [stack]
  • The next larger element [series] [stack]

Minimum stack

👉 [LeetCode express] : 155 minimum stack (simple)

Answer key

→ Click to expand view

/** * initialize your data structure here. */
var MinStack = function() {
    this.stack = [];
    this.minArr = [];
    this.count = 0;
    this.min = Number.MAX_SAFE_INTEGER;
};
/ * * *@param {number} x
 * @return {void}* /
MinStack.prototype.push = function(x) {
    this.min = Math.min(this.min, x);
    this.minArr[this.count] = this.min;
    this.stack[this.count] = x;
    this.count++;
};
/ * * *@return {void}* /
MinStack.prototype.pop = function() {
    const element = this.stack[this.count - 1];
    if (this.count - 2> =0) this.min = this.minArr[this.count - 2];
    else  this.min = Number.MAX_SAFE_INTEGER;
    delete this.stack[this.count - 1];
    delete this.minArr[this.count - 1];
    this.count--;
    return element;
};
/ * * *@return {number}* /
MinStack.prototype.top = function() {
    if (this.count >= 1) {
        return this.stack[this.count - 1];
    }
    return null;
};
/ * * *@return {number}* /
MinStack.prototype.getMin = function() {
    const element = this.minArr[this.count - 1];
    return element;
};
/** * Your MinStack object will be instantiated and called as such: * var obj = new MinStack() * obj.push(x) * obj.pop() * var param_3 = obj.top() * var param_4 = obj.getMin() */

Copy the code

Next larger element stack

  • 👉 [LeetCode express] : 496 Next bigger element I (simple)
  • 👉 [LeetCode express] : 503 Next Larger Element II (medium)

Due to space constraints, only the code template for the first question is given here

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @return {number[]}* /
var nextGreaterElements = function(nums) {
    let ans = [];
    let stack = new Stack();
    const n = nums.length;
    for (let i = 2 * n - 1; i >= 0; i--) {
        while(! stack.isEmpty() && stack.top() <= nums[i % n]) { stack.pop(); } ans[i % n] = stack.isEmpty() ? -1 : stack.top();
        stack.push(nums[i % n]);
    }
    return ans;
};
class Stack {
    constructor() {
        this.count = 0;
        this.items = [];
    }
    top() {
        if (this.isEmpty()) return undefined;
        return this.items[this.count - 1];
    }
    push(element) {
        this.items[this.count] = element;
        this.count++;
    }
    pop() {
        if (this.isEmpty()) return undefined;
        const element = this.items[this.count - 1];
        delete this.items[this.count - 1];
        this.count--;
        return element;
    }
    isEmpty() {
        return this.size() === 0;
    }
    size() {
        return this.count; }}Copy the code

【 答 案 】 【 答 案 】 【 答 案 】

👉 [LeetCode express] : 20 valid parentheses (medium)

Answer key

→ Click to expand view

/ * * *@param {string} s
 * @return {boolean}* /
var isValid = function(s) {
    if (s.length === 0) {
        return true;
    }
    if (s.length % 2! = =0) {
        return false;
    }
    let map = {
        ') ': '('.'] ': '['.'} ': '{'};let left = ['('.'['.'{'];
    let right = [') '.'] '.'} '];
    let stack = new Stack();
    for (let i = 0; i < s.length; i++) {
        if(! right.includes(s[i])) { stack.push(s[i]); }else {
            const matchStr = map[s[i]];
            while(! stack.isEmpty()) {const element = stack.pop();
                if(left.includes(element) && matchStr ! == element)return false;
                if (element === matchStr) break; }}}return stack.isEmpty();
};
class Stack {
    constructor() {
        this.count = 0;
        this.items = [];
    }
    push(element) {
        this.items[this.count] = element;
        this.count++;
    }
    pop() {
        if (this.isEmpty()) return undefined;
        const element = this.items[this.count - 1];
        delete this.items[this.count - 1];
        this.count--;
        return element;
    }
    isEmpty() {
        return this.size() === 0;
    }
    size() {
        return this.count; }}Copy the code

Simplified path [stack]

👉 [LeetCode Express] : 71 simplified path (medium)

Answer key

→ Click to expand view

/ * * *@param {string} path
 * @return {string}* /
var simplifyPath = function(path) {
    let newPath = path.split('/');
    newPath = newPath.filter(item= >item ! = ="");
    const stack = new Stack();
    for (let s of newPath) {
        if (s === '.. ') stack.pop();
        else if(s ! = ='. ') stack.push(s);
    }
    if (stack.isEmpty()) return '/';
    let str = ' ';
    while(! stack.isEmpty()) {const element = stack.pop();
        str = '/' + element + str;
    }
    return str;
};
function handleBack(stack, tag, num) {
    if(! stack.isEmpty())return num;
    const element = stack.pop();
    if (element === '.. ') return handleBack(stack, tag, num + 1);
    else {
        stack.push(element);
        returnnum; }}class Stack {
    constructor() {
        this.count = 0;
        this.items = [];
    }
    push(element) {
        this.items[this.count] = element;
        this.count++;
    }
    pop() {
        if (this.isEmpty()) return undefined;
        const element = this.items[this.count - 1];
        delete this.items[this.count - 1];
        this.count--;
        return element;
    }
    size() {
        return this.count;
    }
    isEmpty() {
        return this.size() === 0; }}Copy the code

【🔥】 High frequency algorithm series: DFS

There are mainly the following high-frequency questions:

  • Maximum area of island [medium] [DFS]
  • Same tree [simple] [DFS]

Maximum size of island [DFS]

👉 [LeetCode through train] : maximum area of 695 islands (medium)

Answer key

→ Click to expand view

/ * * *@param {number[][]} grid
 * @return {number}* /
let maxX, maxY;let visited;let globalMaxArea;
var maxAreaOfIsland = function(grid) {
    visited = new Set(a); maxX = grid.length; maxY = grid[0].length;
    globalMaxArea = 0;
    for (let i = 0; i < maxX; i++) {
        for (let j = 0; j < maxY; j++) {
            if (grid[i][j] === 1) {
                visited.add(` (${i}.${j}) `);
                globalMaxArea = Math.max(globalMaxArea, dfs(grid, i, j)); } visited.clear(); }}return globalMaxArea;
};
function dfs(grid, x, y) {
    let res = 1;
    for (let i = -1; i <= 1; i++) {
        for (let j = -1; j <= 1; j++) {
            if (Math.abs(i) === Math.abs(j)) continue;
            const newX = x + i;
            const newY = y + j;
            if (newX >= maxX || newX < 0 || newY >= maxY || newY < 0) continue;
            if (visited.has(` (${newX}.${newY}) `)) continue;
            visited.add(` (${newX}.${newY}) `);
            const areaCnt = grid[newX][newY]
            if (areaCnt === 1) {
                constcnt = dfs(grid, newX, newY); res += cnt; }}}return res;
}

Copy the code

Same tree [DFS]

👉 [LeetCode express] : 100 same trees (simple)

Answer key

→ Click to expand view

/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; *} * /
/ * * *@param {TreeNode} p
 * @param {TreeNode} q
 * @return {boolean}* /
var isSameTree = function(p, q) {
    if (p == null && q == null) return true;
    if (p == null || q == null) return false;
    if(p.val ! == q.val)return false;
    return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
};

Copy the code

【🔥】 High frequency algorithm series: backtracking algorithm

There are mainly the following high-frequency questions:

  • N queen 【 difficulty 】【 backtracking algorithm 】【 interview 真题】
  • Full permutation [medium] [Backtracking algorithm]
  • Parenthesis generation [medium] [Backtracking algorithm]
  • Restore IP address [medium] [backtracking algorithm]
  • Subset [simple] [Backtracking algorithm]

【 答 案 】N queen 【 Backtracking algorithm 】

👉 [LeetCode express] : 51 N Queen (difficulty)

Answer key

→ Click to expand view

/ * * *@param {number} n
 * @return {string[][]}* /
let result = [];
var solveNQueens = function(n) {
    result = [];
    let board = [];
    for (let i = 0; i < n; i++) {
      board[i] = [];
      for (let j = 0; j < n; j++) {
        board[i][j] = '. '
      }
    }
    backtrack(0, board, n);
    return result;
};
function deepClone(board) {
  let res = [];
  for (let i = 0; i < board.length; i++) {
    res.push(board[i].join(' '));
  }
  return res;
}
function backtrack(row, board, n) {
    if (row === n) {
      result.push(deepClone(board));
      return;
    }
    for (let j = 0; j < n; j++) {
        if (checkInValid(board, row, j, n)) continue;
        board[row][j] = 'Q';
        backtrack(row + 1, board, n);
        board[row][j] = '. '; }}function checkInValid(board, row, column, n) {
  / / line
  for (let i = 0; i < n; i++) {
    if (board[i][column] === 'Q') return true;
  }
  for (let i = row - 1, j = column + 1; i >= 0 && j < n; i--, j++) {
    if (board[i][j] === 'Q') return true;
  }
  for (let i = row - 1, j = column - 1; i >= 0 && j >= 0; i--, j--) {
    if (board[i][j] === 'Q') return true;
  }
  return false;
}

Copy the code

Full permutation [backtracking algorithm]

👉 [LeetCode express] : 46 Full array (medium)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @return {number[][]}* /
let results = [];var permute = function(nums) {
    results = [];
    backtrack(nums, []);
    return results;
};
function backtrack(nums, track) {
    if (nums.length === track.length) {
        results.push(track.slice());
        return;
    }
    for (let i = 0; i < nums.length; i++) {
        if (track.includes(nums[i])) continue; track.push(nums[i]); backtrack(nums, track); track.pop(); }}Copy the code

Generation of parentheses [backtracking algorithm]

👉 [LeetCode express] : 22

Answer key

→ Click to expand view

/ * * *@param {number} n
 * @return {string[]}* /
var generateParenthesis = function(n) {
    let validRes = [];
    backtrack(n * 2, validRes, ' ');
    return validRes;
};
function backtrack(len, validRes, bracket) {
    if (bracket.length === len) {
        if (isValidCombination(bracket)) {
            validRes.push(bracket);
        }
        return;
    }
    for (let str of ['('.') ']) {
        bracket += str;
        backtrack(len, validRes, bracket);
        bracket = bracket.slice(0, bracket.length - 1); }}function isValidCombination(bracket) {
    let stack = new Stack();
    for (let i = 0; i < bracket.length; i++) {
        const str = bracket[i];
        if (str === '(') {
            stack.push(str);
        } else if (str === ') ') {
            const top = stack.pop();
            if(top ! = ='(') return false; }}return stack.isEmpty();
}
class Stack {
    constructor() {
        this.count = 0;
        this.items = [];
    }
    push(element) {
        this.items[this.count] = element;
        this.count++;
    }
    pop() {
        if (this.isEmpty()) return;
        const element = this.items[this.count - 1];
        delete this.items[this.count - 1];
        this.count--;
        return element;
    }
    size() {
        return this.count;
    }
    isEmpty() {
        return this.size() === 0; }}Copy the code

Restore IP address [backtracking algorithm]

👉 [LeetCode] : 93 Restore IP address (medium)

Answer key

→ Click to expand view

/ * * *@param {string} s
 * @return {string[]}* /
var restoreIpAddresses = function(s) {
    if (s.length > 12) return [];
    let res = [];
    const track = [];
    backtrack(s, track, res);
    return res;
};
function backtrack(s, track, res) {
    if (track.length === 4 && s.length === 0) {
        res.push(track.join('. '));
        return;
    }
    let len = s.length >= 3 ? 3 : s.length;
    for (let i = 0; i < len; i++) {
        const c = s.slice(0, i + 1);
        if (parseInt(c) > 255) continue;
        if (i >= 1 &&  parseInt(c) < parseInt((1 + '0'.repeat(i)))) continue;
        track.push(c);
        backtrack(s.slice(i + 1), track, res); track.pop(); }}Copy the code

Subset [backtracking algorithm]

👉 [LeetCode express] : 78 subsets (medium)

Answer key

→ Click to expand view

/ * * *@param {number[]} nums
 * @return {number[][]}* /
var subsets = function(nums) {
    if (nums.length === 0) return[[]].let resArr = [];
    backtrack(nums, 0, [], resArr);
    return resArr;
};
function backtrack(nums, index, subArr, resArr) {
    if (Array.isArray(subArr)) {
        resArr.push(subArr.slice());
    }
    if (index === nums.length) {
        return;
    } 
    for (let i = index; i < nums.length; i++) {
        subArr.push(nums[i]);
        backtrack(nums, i + 1, subArr, resArr); subArr.pop(nums[i]); }}Copy the code

At the end of the article’s welfare

Recommend a very helpful brush algorithm url, Labuladong algorithm cheat sheet, through the routine, look for high frequency topics, direct dacaang; The book has been published as a book, the corresponding Github repository is also 86.2k Star, and the author is still updated frequently, very worth learning!

❤ ️ thank you

Past pure text

  • Bytedance favorite test :JavaScript foundation 2696 👍
  • Bytedance favorite test front end questions :CSS foundation 687 👍
  • Bytedance love test of the front face: computer network foundation 761 👍

Welcome to the public number: Tuque community.

If you want to learn a skill from scratch in a practical way, or want to do a more complete project to prepare for the interview, I believe the content of “Tuque community” can help you, become the compass on the way to your growth.

The original is not easy to

Like the words of the original is not easy, give some encouragement ❤️ don’t forget to share, like, in the third oh ~.