leetcode - 103 introductory basic questions

1, leetcode - string
2, leetcode - binary, mathematical class
3, leetcode - array
4, leetcode - binary search
5, leetcode - speed pointer
6, leetcode - sliding window
7, leetcode - matrix
8, leetcode - stack and queue
9, leetcode - linked list
10, leetcode - binary tree
11, leetcode - join search set
12, leetcode - backtracking
13, leetcode - dynamic programming
14, leetcode - greedy

1, leetcode - string

344. Reverse string

Input: s = [ "h", "e", "l", "l", "o" ]
Output:     [ "o", "l", "l", "e", "h" ]
/**
 * @param {character[]} s
 * @return {void} Do not return anything, modify s in-place instead.
 */
var reverseString = function(s) {
    return s.reverse();
};
[ 'o', 'e', 'l', 'l', 'h' ] 
[ 'o', 'l', 'l', 'e', 'h' ] 
[ 'o', 'l', 'l', 'e', 'h' ]
/**
/**
 * @param {character[]} s
 * @return {void} Do not return anything, modify s in-place instead.
 */
var reverseString = function(s) {
    let l = 0;
    let r = s.length - 1;
    while(l <= r) {
        // let temp = s[l];
        // s[l] = s[r];
        // s[r] = temp;
        [s[l], s[r]] = [s[r], s[l]];
        l++;
        r--;
        console.info(s);
    }
    return s;
};

9. Number of palindromes

Input: x = 121
 Output: true
1 1 
2 2
Input: x = -121
 Output: false
 Explanation: read from left to right, by -121 .  Read right to left, Is 121- . Therefore, it is not a palindrome number.
- 1
/**
 * @param {number} x
 * @return {boolean}
 */
var isPalindrome = function(x) {
    let arr = x.toString();
    let len = arr.length;
    for(let i = 0; i < len/2; i++) {
        console.info(arr[i] + '  ' + arr[len - 1 - i]);
        if(arr[i] !== arr[len - 1 - i]) {
            return false;
        }
    }
    return true;
};
/**
 * @param {number} x
 * @return {boolean}
 */
var isPalindrome = function(x) {
    return x.toString() === x.toString().split('').reverse().join('');
};

125. Validate palindrome string

input: "A man, a plan, a canal: Panama"
output: true
 Explanation: "amanaplanacanalpanama" It's a palindrome string
amanaplanacanalpanama // Keep only letters and numbers
a a 
m m 
a a 
n n 
a a 
p p 
l l 
a a 
n n 
a a 
c c  // Finally, the subscript coincidence c compares itself with itself
/**
 * @param {string} s
 * @return {boolean}
 */
var isPalindrome = function(s) {
    s = s.toLowerCase().replace(/[^a-z0-9]/g, '');
    console.info(s);
    let l = 0;
    let r = s.length - 1;
    while(l <= r) {
        console.info(s[l] + ' ' + s[r]);
        if(s[l] !== s[r]) return false;
        l++;
        r--;
    }
    return true;
};

28. Implement str ()

Here are two strings haystack and need. Please find the first position of the need string in the haystack string (the subscript starts from 0). If it does not exist, - 1 is returned.

Input: haystack = "hello", needle = "ll"
Output: 2
h l 
e l 
l l 
ll ll
/**
 * @param {string} haystack
 * @param {string} needle
 * @return {number}
 */
var strStr = function(haystack, needle) {
    if(needle.length === 0) return 0;
    let res = -1;
    for(let i = 0; i < haystack.length; i++) {
        console.info(haystack[i] + ' ' + needle[0]);
        if(haystack[i] === needle[0]) {
            console.info(haystack.substring(i, needle.length + i) + ' ' + needle);
            if(haystack.substring(i, needle.length + i) === needle) {
                res = i;
                break;
            }
        }
    }
    return res;
};

387. First unique character in a string

Given a string, find its first non repeating character and return its index. If it does not exist, - 1 is returned.

s = "leetcode"
Return 0
{ l: 1, e: 3, t: 1, c: 1, o: 1, d: 1 }
/**
 * @param {string} s
 * @return {number}
 */
var firstUniqChar = function(s) {
    let map = {};
    for(let item of s){
        map[item] = (map[item] || 0) + 1;
    }
    console.info(map);
    for(let i = 0; i < s.length; i++){
        if(map[s[i]] === 1) return i;
    }
    return -1;
};

242. Valid acronyms

If each character in S and t appears the same number of times, s and T are called alphabetic words.

input: s = "anagram", t = "nagaram"
output: true 
{ a: 1, n: -1 } 
{ a: 0, n: 0 } 
{ a: 1, n: 0, g: -1 } 
{ a: 0, n: 0, g: 0 } 
{ a: 0, n: 0, g: 0, r: 0 } 
{ a: 0, n: 0, g: 0, r: 0 } 
{ a: 0, n: 0, g: 0, r: 0, m: 0 }
/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var isAnagram = function(s, t) {
    let sLen = s.length;
    let tLen = t.length;
    if(sLen !== tLen) return false;
    let count = {};
    for(let i = 0; i < sLen; i++) {
        count[s[i]] ? count[s[i]]++ : count[s[i]] = 1;
        count[t[i]] ? count[t[i]]-- : count[t[i]] = -1;
        console.info(count);
    }
    return Object.values(count).every(item => item === 0);
};

383. Ransom letter

Given a ransom string and a magazine string, judge whether the first string ransom can be composed of the characters in the second string magazines. If it can be constructed, return true; Otherwise, false is returned.

(Title Description: in order not to expose the handwriting of the ransom letter, search the required letters from the magazine to form words to express their meaning. Each character in the magazine string can only be used once in the ransom letter string.)

Input: ransomNote = "aa", magazine = "aab"
Output: true
{ a: 2, b: 1 }  // Characters contained in the magazine
{ a: 1, b: 1 }  // One a was used in the ransom letter
{ a: 0, b: 1 }  // Another a was used in the ransom letter
/**
 * @param {string} ransomNote
 * @param {string} magazine
 * @return {boolean}
 */
var canConstruct = function(ransomNote, magazine) {
    let map = {}; 
    // Count the number of letters in the magazine
    for(const s of magazine) {
        map[s] = (map[s] || 0) + 1;
    }
    console.info(map);
    // Delete the characters used in the ransom letter from the magazine one by one. If the magazine lacks the characters to be used, it will directly return false
    for(const s of ransomNote) { 
        if(!map[s]) return false;
        map[s]--;
        console.info(map);
    }
    return true;
};
ab // One a was used in the ransom letter
b  // Another a was used in the ransom letter
/**
 * @param {string} ransomNote
 * @param {string} magazine
 * @return {boolean}
 */
var canConstruct = function(ransomNote, magazine) {
    // Traverse the ransom letter directly. If there are no characters in the magazine, it will directly return false
    // If there is in the magazine, delete the character from the magazine because it has been used
    for (let i = 0; i < ransomNote.length; i++) {
        let s = ransomNote[i];
        if(magazine.indexOf(s) === -1) return false;
        magazine = magazine.replace(s, '');
        console.info(magazine);
    }
    return true;
};

2, leetcode - binary, mathematical class

191. Number of bit 1

Input: 0000000000000000000000001011
 Output: 3
 Explanation: there are three digits in the binary string 0000000000000000000000000000001011 '1'. 
Remove the last 1 in the binary each time
1010 
1000 
0
/**
 * @param {number} n - a positive integer
 * @return {number}
 */
var hammingWeight = function(n) {
    let res = 0;
    while(n) {
        n = (n - 1) & n;
        res++;
        console.info(parseInt(n).toString(2));
    }
    return res;
};

326. Power of 3

Input: n = 27
 Output: true
9 
3 
1
Input: n = 45
 Output: false
15 
5 
1.6666666666666667
/**
 * @param {number} n
 * @return {boolean}
 */
var isPowerOfThree = function(n) {
    while(n >= 3) {
        n = n / 3;
        console.info(n);
    }
    return n === 1;
};

136. Figures that appear only once

input: [2,2,1]
output: 1
The XOR operation of the same value is 0, and the XOR operation with 0 is the original value
res  Operation process
0    2^2=0
1    0^1=1
/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
    let res = nums[0];
    for(let i = 1; i < nums.length; i++) {
        res ^= nums[i];
        console.info(res);
    }
    return res;
};

172. Factorial zero

Input: n = 5
 Output: 1
 Explanation: 5! = 120 ,There is a trailing 0
1
/**
 * @param {number} n
 * @return {number}
 */
var trailingZeroes = function(n) {
    let res = 0;
    while(n > 1) {
        n = (n / 5 | 0);
        res += n;
        console.info(n);
    }
    return res;
};

7. Integer inversion

Input: x = -123   Output: -321
 Input: x = 120    Output: 21
res=-3   x=-12 
res=-32  x=-1 
res=-321 x=0

res=0  x=12 
res=2  x=1 
res=21 x=0
/**
 * @param {number} x
 * @return {number}
 */
var reverse = function(x) {
    let res = 0;
    let min = Math.pow(-2, 31);
    let max = Math.pow(2, 31) - 1;
    while(x) {
        res = res * 10 + x % 10; // X% 10: take decimal digits
        if(res > max || res < min) return 0;
        x = x / 10 | 0; // Take a number with more than 10 decimal digits
        console.info('res='+res+' x='+x);
    }
    return res;
};

171. Excel table column serial number

input: columnTitle = "AB"
output: 28
1 
28
/**
 * @param {string} columnTitle
 * @return {number}
 */
var titleToNumber = function(columnTitle) {
    let ans = 0;
    for(let item of columnTitle){
        ans = ans * 26 + (item.charCodeAt() - 'A'.charCodeAt() + 1);
        console.info(ans);
    }
    return ans;
};

190. Reverse binary

Input: n = 00000010100101000001111010011100
 Output: 964176192 (00111001011110000010100101000000)
Explanation: the input binary string 000000 1010010100000111010011100 represents an unsigned integer 43261596,
     Therefore, 964176192 is returned, and its binary representation is 001110010111100000010100101000000.
32 Cycle, move one bit at a time
0 - 1010010100000111101001110 
0 - 101001010000011110100111 
1 - 10100101000001111010011 
11 - 1010010100000111101001 
111 - 101001010000011110100 
1110 - 10100101000001111010 
11100 - 1010010100000111101 
111001 - 101001010000011110 
1110010 - 10100101000001111 
11100101 - 1010010100000111 
111001011 - 101001010000011 
1110010111 - 10100101000001 
11100101111 - 1010010100000 
111001011110 - 101001010000 
1110010111100 - 10100101000 
11100101111000 - 1010010100 
111001011110000 - 101001010 
1110010111100000 - 10100101 
11100101111000001 - 1010010 
111001011110000010 - 101001 
1110010111100000101 - 10100 
11100101111000001010 - 1010 
111001011110000010100 - 101 
1110010111100000101001 - 10 
11100101111000001010010 - 1 
111001011110000010100101 - 0 
1110010111100000101001010 - 0 
11100101111000001010010100 - 0 
111001011110000010100101000 - 0 
1110010111100000101001010000 - 0 
11100101111000001010010100000 - 0 
111001011110000010100101000000 - 0 
964176192
/**
 * @param {number} n - a positive integer
 * @return {number} - a positive integer
 */
var reverseBits = function(n) {
    let result = 0
    for (let i = 0; i < 32; i++) {
        result = (result << 1) + (n & 1); // Get the last bit of binary and keep moving left
        n = n >> 1; // The original binary number keeps moving to the right
        console.info(parseInt(result).toString(2)+' - '+parseInt(n).toString(2));
    }
    // Why > > > 0? A javascript has no unsigned integers and is all signed
    // If not > > > 0, the resulting value is negative, but unsigned integers are unsigned
    // The way to convert javascript from signed to unsigned is > > > 0
    console.info(result >>> 0);
    return result >>> 0;
};

3, leetcode - array

217. There are duplicate elements

input: [1,2,3,1]
output: true
/**
 * @param {number[]} nums
 * @return {boolean}
 */
var containsDuplicate = function(nums) {
    let map = {};
    for(let item of nums) {
        if(map[item]) {
            return true;
        }
        map[item] = true;
    }
    return false;
};

349. Intersection of two arrays

Each element in the output result must be unique

map double cycle

Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2]
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersection = function(nums1, nums2) {
    let map = {};
    let res = [];
    for(let item of nums1) {
        map[item] = true;
    }
    for(let item of nums2) {
        if(map[item]) {
            res.push(item);
            map[item] = false;
        }
    }
    return res;
};

350. Intersection of two arrays II

The number of occurrences of each element in the output result shall be consistent with the minimum number of occurrences of elements in the two arrays

Double array double pointer

Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2,2]
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    let map = {};
    let res = [];
    for(let item of nums1) {
        map[item] = (map[item] || 0) + 1;
    }
    for(let item of nums2) {
        if(map[item]) {
            res.push(item);
            map[item]--;
        }
    }
    return res;
};
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    nums1.sort((a, b) => a - b);
    nums2.sort((a, b) => a - b);
    let res = [];
    let l1 = nums1.length - 1;
    let l2 = nums2.length - 1;
    while(l1 >= 0 && l2 >= 0) {
        if(nums1[l1] === nums2[l2]) {
            res.push(nums1[l1]);
            l1--;
            l2--;
        }
        if(nums1[l1] > nums2[l2]) l1--;
        if(nums1[l1] < nums2[l2]) l2--;
    }
    return res;
};
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    let res = [];
    let l1 = 0;
    let l2 = 0;
    nums1.sort((a, b) => a - b);
    nums2.sort((a, b) => a - b);
    while(l1 < nums1.length && l2 < nums2.length) {
        if(nums1[l1] === nums2[l2]) {
            res.push(nums1[l1]);
            l1++;
            l2++;
        }
        if(nums1[l1] > nums2[l2]) {
            l2++;
        }
        if(nums1[l1] < nums2[l2]) {
            l1++;
        }
    }
    return res;
};

1. Sum of two numbers Input unordered array

map

Input: nums = [2,7,11,15], target = 9
 Output:[0,1]
Explanation: because nums[0] + nums[1] == 9 ,return [0, 1] . 
Input: nums = [3,2,4], target = 6
 Output: [1,2]
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    let map = {};
    for(let i = 0; i < nums.length; i++) {
        if(map[nums[i]] !== undefined) {
            return [map[nums[i]], i];
        }
        map[target - nums[i]] = i;
    }
};

167. Sum of two numbers II Input ordered array

Odd group left-right collision pointer

Input: numbers = [2,7,11,15], target = 9
 Output:[1,2]
Explanation: the sum of 2 and 7 is equal to the target number 9. therefore index1 = 1, index2 = 2 . 
/**
 * @param {number[]} numbers
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(numbers, target) {
    let l = 0;
    let r = numbers.length - 1;
    while(l <= r) {
        if(numbers[l] + numbers[r] === target) return [l+1, r+1];
        if(numbers[l] + numbers[r] > target) r--;
        if(numbers[l] + numbers[r] < target) l++;
    }
};

977. Square of ordered array

Give you an integer array nums sorted in non decreasing order, and return a new array composed of the square of each number. It is also required to sort in non decreasing order.

Odd group left-right collision pointer

Input: nums = [-4,-1,0,3,10]
Output:[0,1,9,16,100]
Explanation: after squaring, the array becomes [16,1,0,9,100]
After sorting, the array becomes [0,1,9,16,100]
/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function(nums) {
    let res = [];
    let l = 0;
    let r = nums.length -1;
    while(l <= r){
        let l_val = nums[l] * nums[l];
        let r_val = nums[r] * nums[r];
        if(l_val <= r_val) {
            res.unshift(r_val);
            r--;
        }else{
            res.unshift(l_val);
            l++;
        }
    }
    return res;
};

11. Container containing the most water

Odd group left-right collision pointer

Give you n nonnegative integers a1, a2,..., an, each representing a point (i, ai) in the coordinate. Draw n vertical lines in the coordinates. The two endpoints of the vertical line i are (i, ai) and (i, 0). Find the two lines so that the container formed by them and the x-axis can hold the most water.

Note: you cannot tilt the container.

Input:[1,8,6,2,5,4,8,3,7]
Output: 49 
Explanation: the vertical line in the figure represents the input array [1,8,6,2,5,4,8,3,7]. In this case, the maximum value that the container can hold water (represented by the blue part) is 49.
/**
 * @param {number[]} height
 * @return {number}
 */
var maxArea = function(height) {
    let l = 0;
    let r = height.length - 1;
    let res = 0;
    while(l < r) {
        if(height[l] <= height[r]) {
            res = Math.max(height[l] * (r - l), res);
            l++
        } else {
            res = Math.max(height[r] * (r - l), res);
            r--
        }
    }
    return res;
};

15. Sum of three

Odd group left-right collision pointer

Give you an array num containing n integers. Judge whether there are three elements a, b and c in num, so that a + b + c = 0? Please find all triples with sum 0 and no repetition.

Note: the answer cannot contain duplicate triples.

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function(nums) {
    let res = [];
    nums.sort((a, b) => a - b);
    for(let i = 0; i < nums.length - 2; i++) {
        let cur = nums[i];
        if(i - 1 >= 0 && cur === nums[i - 1]) continue;
        let left = i + 1;
        let right = nums.length - 1;
        while(left < right) {
            let l = nums[left];
            let r = nums[right];
            if(l + r + cur === 0) {
                res.push([cur, l, r]);
                // Skip the same values on the left and right
                while(left < right && nums[left] === l) left++;
                while(left < right && nums[right] === r) right--;

            }
            if(l + r + cur > 0) right--;
            if(l + r + cur < 0) left++;
        }
    }
    return res;
};

88. Merge two ordered arrays

Double array double pointer

Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
 Output:[1,2,2,3,5,6]
Explanation: consolidation is required [1,2,3] and [2,5,6] . 
The combined result is [1,2,2,3,5,6] ,Where bold italics are nums1 Elements in.
/**
 * @param {number[]} nums1
 * @param {number} m
 * @param {number[]} nums2
 * @param {number} n
 * @return {void} Do not return anything, modify nums1 in-place instead.
 */
var merge = function(nums1, m, nums2, n) {
    let len = m + n - 1;
    let mLen = m - 1;
    let nLen = n - 1;
    while(mLen >= 0 && nLen >= 0) {
        if(nums1[mLen] > nums2[nLen]) {
            nums1[len] = nums1[mLen];
            mLen--;
        } else {
            nums1[len] = nums2[nLen];
            nLen--;
        }
        len--;
    }
    while(nLen >= 0) {
        nums1[len] = nums2[nLen];
        nLen--;
        len--
    }
};

14. Longest common prefix

Use reduce to compare two pairs.

Input: strs = ["flower","flow","flight"]
Output: "fl"
/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function(strs) {
    let len = strs.length;
    if(len === 0) return '';
    if(len === 1) return strs[0];
    return strs.reduce(function(a, b) {
        let res = '';
        for(let i = 0; i < a.length; i++) {
            if(a[i] === b[i]) {
                res += a[i];
            } else {
                break;
            }
        }
        return res;
    });
};

169. Most elements

map

Given an array of size n, find most of its elements. Most elements refer to elements that appear more than ⌊ n/2 ⌋ in the array.

You can assume that the array is non empty and that there are always many elements in a given array.

Input: [3,2,3]
Output: 3
/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    let count = {};
    let mid = nums.length >> 1;
    for(let i = 0; i < nums.length; i++) {
        const element = nums[i];
        count[element] ? count[element]++ : count[element] = 1;
        if(count[element] > mid) {
            return element;
        }
    }
};

17. Letter combination of telephone number

Given a string containing only the numbers 2-9, returns all the letter combinations it can represent. The answers can be returned in any order.

The number to letter mapping is given as follows (the same as the telephone key). Note that 1 does not correspond to any letter.

Input: digits = "23"
Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
/**
 * @param {string} digits
 * @return {string[]}
 */
var letterCombinations = function(digits) {
    if(digits.length === 0) return [];
    const res = [];
    const map = { '2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz' };
    function dfs(str, deep) {
        console.info(str);
        if(str.length === digits.length){
            res.push(str);
            return;
        }
        let curStr = map[digits[deep]];
        for(let i = 0; i < curStr.length; i++) {
            dfs(str + curStr[i], deep + 1);
        }
    }
    dfs('', 0); 
    return res;
};

4, leetcode - binary search

Math.floor(left + (right - left) / 2)

704. Binary search

Given an n-element ordered (ascending) integer array nums and a target value target, write a function to search the target in nums. If the target value exists, return the subscript, otherwise return - 1.

input: nums = [-1,0,3,5,9,12], target = 9
 output: 4
 explain: 9 Appear in nums Middle and subscript 4
left=0 right=5 mid=2 nums[mid]=3 
left=3 right=5 mid=4 nums[mid]=9
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    let left = 0;
    let right = nums.length - 1;
    let res = -1;
    while(left <= right) {
        let mid = (right + left) >> 1;
        console.info('left='+left+' right='+right);
        console.info('mid='+mid+' nums[mid]='+nums[mid]);
        if(nums[mid] === target) {
            res = mid;
            break;
        } 
        if(nums[mid] > target) right = mid - 1;
        if(nums[mid] < target) left = mid + 1;
    }
    return res;
};

875. Ke Ke, who likes bananas

Ke Ke likes bananas. There are N piles of bananas and piles[i] bananas in pile I. The guard has left and will be back in H hours.

Koko can determine the speed K (root / hour) at which she eats bananas. Every hour, she will choose a pile of bananas and eat K of them. If the pile of bananas is less than k, she will eat all the bananas in the pile, and then she will not eat more bananas within an hour.

Ke Ke likes to eat slowly, but still wants to eat all the bananas before the guard comes back.

Returns the minimum speed K at which she can eat all bananas in H hours (k is an integer).

input: piles = [3,6,7,11], H = 8
 output: 4
/**
 * @param {number[]} piles
 * @param {number} h
 * @return {number}
 */
var minEatingSpeed = function(piles, h) {
    let left = 1;
    let right = Math.max(...piles);
    while (left <= right) {
        const mid = Math.floor(left + (right - left) / 2);
        if (canFinish(piles, mid, h)) {
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return left;
};
function canFinish (piles, speed, h) {
    let time = 0;
    for (let n of piles) {
        time += (n / speed | 0) + ((n % speed > 0) ? 1 : 0);
    }
    return time <= h;
}

35. Search insertion position

Given a sort array and a target value, find the target value in the array and return its index. If the target value does not exist in the array, returns the position where it will be inserted in order.

You must use an algorithm with a time complexity of O(log n).

input: nums = [1,3,5,6], target = 5
 output: 2
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert = function(nums, target) {
    let left = 0;
    let right = nums.length - 1;
    let index = nums.length;
    while(left <= right){
        let mid = (left + right) >> 1;
        if(target > nums[mid]) {
            left =  mid + 1;
        } else {
            index = mid;
            right = mid - 1;
        }
    }
    return index;
};

69. Sqrt(x)

Give you a nonnegative integer x, calculate and return the arithmetic square root of X.

Since the return type is an integer, only the integer part will be retained and the decimal part will be rounded off.

Note: it is not allowed to use any built-in exponential functions and operators, such as pow(x, 0.5) or x ** 0.5.

Input: x = 8
 Output: 2
 Explanation: the arithmetic square root of 8 is 2.82842..., Since the return type is an integer, the decimal part will be rounded off.
/**
 * @param {number} x
 * @return {number}
 */
var mySqrt = function(x) {
    let [l,r] = [0,x];
    let ans = -1;
    while(l <= r){
        const mid = (l+r) >> 1;
        if(mid * mid > x){
            r = mid - 1;
        } else {
            ans = mid;
            l = mid + 1;
        }
    }
    return ans;
};

278. First wrong version

You are a product manager and are currently leading a team to develop new products. Unfortunately, the latest version of your product has not passed the quality test. Since each version is developed based on the previous version, all versions after the wrong version are wrong.

Suppose you have n versions [1, 2,..., n], you want to find the first wrong version that causes errors in all subsequent versions.

You can call the bool isBadVersion(version) interface to determine whether the version number is wrong in the unit test. Implement a function to find the first wrong version. You should minimize the number of calls to the API.

Input: n = 5, bad = 4
 Output: 4
 Explanation:
call isBadVersion(3) -> false 
call isBadVersion(5) -> true 
call isBadVersion(4) -> true
 So, 4 is the first wrong version.
/**
 * Definition for isBadVersion()
 * 
 * @param {integer} version number
 * @return {boolean} whether the version is bad
 * isBadVersion = function(version) {
 *     ...
 * };
 */

/**
 * @param {function} isBadVersion()
 * @return {function}
 */
var solution = function(isBadVersion) {
    /**
     * @param {integer} n Total versions
     * @return {integer} The first bad version
     */
    return function(n) {
        let left = 0; let right = n - 1;
        let res = n;
        while (left <= right) {
            const mid = Math.floor(left + (right - left) / 2);
            if (isBadVersion(mid)) {
                res = mid;
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return res;
    };
};

5, leetcode - speed pointer

26. Delete duplicates in the ordered array

Input: nums = [1,1,2]
Output: 2, nums = [1,2]
Explanation: the function should return a new length of 2 and the original array nums The first two elements of are modified to 1, 2 . 
     There is no need to consider the elements in the array that exceed the new length.
              Before modification          After modification         Modified slow
slow=0 fast=0 [ 1, 1, 1, 2 ] [ 1, 1, 1, 2 ] slow=0 
slow=0 fast=1 [ 1, 1, 1, 2 ] [ 1, 1, 1, 2 ] slow=0 
slow=0 fast=2 [ 1, 1, 1, 2 ] [ 1, 1, 1, 2 ] slow=0 
slow=0 fast=3 [ 1, 1, 1, 2 ] [ 1, 2, 1, 2 ] slow=1
/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
    let slow = 0; // Previous elements, including slow pointers, are not repeated
    let fast = 0;
    while(fast < nums.length) {
        console.info('slow='+slow+' fast='+fast);
        console.info(nums);
        if(nums[fast] !== nums[slow]) {
            nums[slow + 1] = nums[fast];
            slow++;
        }
        fast++;
        console.info(nums);
        console.info('slow='+slow);
    }
    return slow + 1; // slow is a subscript starting from 0, so the length needs to be + 1
};

27. Remove element

Give you an array num and a value val, you need In situ Removes all elements with a value equal to val and returns the new length of the array after removal.

Input: nums = [3,2,2,3], val = 3
 Output: 2, nums = [2,2]
Explanation:
    The function should return a new length of 2, also nums The first two elements in are both 2.
    You don't need to consider the elements in the array that exceed the new length.
    For example, the new length returned by the function is 2, and nums = [2,2,3,3] or nums = [2,2,0,0],It will also be regarded as the correct answer.
              Before modification          After modification         Modified slow
slow=0 fast=0 [ 3, 2, 2, 3 ] [ 3, 2, 2, 3 ] slow=0 
slow=0 fast=1 [ 3, 2, 2, 3 ] [ 2, 2, 2, 3 ] slow=1 
slow=1 fast=2 [ 2, 2, 2, 3 ] [ 2, 2, 2, 3 ] slow=2 
slow=2 fast=3 [ 2, 2, 2, 3 ] [ 2, 2, 2, 3 ] slow=2
/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
    let slow = 0; // The elements before the slow pointer remove the target element
    let fast = 0;
    while(fast < nums.length) {
        console.info('slow='+slow+' fast='+fast);
        console.info(nums);
        if(nums[fast] !== val){
            nums[slow] = nums[fast];
            slow++;
        }
        fast++;
        console.info(nums);
        console.info('slow='+slow);
    }
    return slow;
};

283. Move zero

Speed pointer

input: [0,1,0,3,12]
output: [1,3,12,0,0]
/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let slow = 0;
    for(let i = 0; i < nums.length; i++) {
        if(nums[i] !== 0) {
            [nums[i], nums[slow]] = [nums[slow], nums[i]];
            slow++;
        }
    }
};
              Before modification              After modification             Modified slow
slow=0 fast=0 [ 0, 1, 0, 3, 12 ] [ 0, 1, 0, 3, 12 ] slow=0 
slow=0 fast=1 [ 0, 1, 0, 3, 12 ] [ 1, 0, 0, 3, 12 ] slow=1 
slow=1 fast=2 [ 1, 0, 0, 3, 12 ] [ 1, 0, 0, 3, 12 ] slow=1 
slow=1 fast=3 [ 1, 0, 0, 3, 12 ] [ 1, 3, 0, 0, 12 ] slow=2 
slow=2 fast=4 [ 1, 3, 0, 0, 12 ] [ 1, 3, 12, 0, 0 ] slow=3
/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let slow = 0;  // The elements before the slow pointer do not contain 0 elements
    let fast = 0;
    while(fast < nums.length) {
        if(nums[fast] !== 0) {
            let temp = nums[slow];
            nums[slow] = nums[fast];
            nums[fast] = temp;
            slow++;
        }
        fast++;
    }
};

6, leetcode - sliding window

3. Longest substring without repeated characters

Given a string s, please find the length of the longest substring that does not contain duplicate characters.

input: s = "abcabcbb"
output: 3 
explain: Because the longest substring without duplicate characters is "abc",So its length is 3.
{ a: 1 }             l=0 r=1 res=1 
{ a: 1, b: 1 }       l=0 r=2 res=2 
{ a: 1, b: 1, c: 1 } l=0 r=3 res=3 
{ a: 1, b: 1, c: 1 } l=1 r=4 res=3 
{ a: 1, b: 1, c: 1 } l=2 r=5 res=3 `
{ a: 1, b: 1, c: 1 } l=3 r=6 res=3 
{ a: 0, b: 1, c: 1 } l=5 r=7 res=3 
{ a: 0, b: 1, c: 0 } l=7 r=8 res=3
/**
 * @param {string} s
 * @return {number}
 */
 var lengthOfLongestSubstring = function(s) {
    let l = 0;
    let r = 0;
    let res = 0;
    let map = {}; // Maintain a window without duplicate characters
    while(r < s.length) {
        let temp = s[r];
        r++; // Always expand the window until there is no repetition of its contents
        map[temp] = (map[temp] || 0) + 1; // Add window content
        while(map[temp] > 1) { // If the contents of the window are repeated, the window will be reduced
            map[s[l]]--; // Reduce window content
            l++; // contract the window
        }
        res = Math.max(res, r-l); // Update longest substring length
        console.info(map);
        console.info('l='+l);
        console.info('r='+r);
        console.info('res='+res);
    }
    return res;
};
/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function(s) {
    let l = 0; let r = 0;
    let res = 0; let map = new Map();
    while(r < s.length) {
        while(map.has(s[r])) {
            map.delete(s[l]);
            l++;
        }
        map.set(s[r], 1);
        r++;
        res = Math.max(res, r - l);
    }
    return res;
};

209. Minimum length subarray

Given an array containing n positive integers and a positive integer target.

Find out the continuous sub array [numsl, numsl+1,..., numsr-1, numsr] with the smallest length satisfying its sum ≥ target in the array, and return its length. If there is no eligible subarray, 0 is returned.

Input: target = 7, nums = [2,3,1,2,4,3]
Output: 2
 Explanation: subarray [4,3] Is the subarray with the smallest length under this condition.
2 l=0 r=1 res=Infinity 
5 l=0 r=2 res=Infinity 
6 l=0 r=3 res=Infinity 
6 l=1 r=4 res=4 
6 l=3 r=5 res=3 
3 l=5 r=6 res=2
/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    let l = 0; let r = 0;
    let res = Infinity; 
    let sum = 0; // Maintain the sum of a sub array greater than or equal to target
    while(r < nums.length) {
        let cur = nums[r];
        r++; // Always expand the window until the sum of subarrays is greater than or equal to target
        sum += cur;
        while(sum >= target) { // If the sum of the subarray is greater than or equal to target, the window is reduced
            res = Math.min(res, r - l); // Update the subarray with the smallest length
            sum -= nums[l];
            l++; // contract the window
        }
        console.info(sum);
        console.info('l='+l);
        console.info('r='+r);
        console.info('res='+res);
    }
    return res === Infinity ? 0 : res;
};

904. Fruit baskets

Input: [1,2,3,2,2]
Output: 4
 Explanation: we can collect [2,3,2,2] If we start with the first tree, we will only be able to collect [1, 2]. 
{ '1': 1 }                 l=0 r=1 res=1 
{ '1': 1, '2': 1 }         l=0 r=2 res=2 
{ '1': 0, '2': 1, '3': 1 } l=1 r=3 res=2 
{ '1': 0, '2': 2, '3': 1 } l=1 r=4 res=3 
{ '1': 0, '2': 3, '3': 1 } l=1 r=5 res=4
/**
 * @param {number[]} fruits
 * @return {number}
 */
var totalFruit = function(tree) {
    let l = 0; let r = 0;
    let map = {}; // Maintain a window with a continuous fruit category of 2
    let count = 0; // Can carry up to 2 types of fruits
    let res = 0; // Maximum amount of fruit trees that can be collected
    while(r < tree.length) {
        let cur = tree[r];
        r++; // Always expand the window before collecting continuous fruit types greater than 2
        if(map[cur]) {
            map[cur]++;
        } else {
            map[cur] = 1;
            count++; // Increase the type of fruit currently collected
        }
        while(count > 2) { // If the type of continuous fruit collected is greater than 2, narrow the window
            map[tree[l]]--;
            if(!map[tree[l]]) count--; // Reduce the type of fruit currently collected
            l++;
        }
        res = Math.max(res, r - l);
        console.info(map);
        console.info('l='+l);
        console.info('r='+r);
        console.info('res='+res);
    }
    return res;
};

1052. Angry bookstore owner

Input: customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3
 Output: 16
 Explanation:
The bookstore owner kept calm in the last three minutes.
Maximum number of satisfied customers = 1 + 1 + 1 + 1 + 7 + 5 = 16.
count=0 l=0 r=1 r-l=1 max=0 
count=0 l=0 r=2 r-l=2 max=0 
count=0 l=0 r=3 r-l=3 max=0 
count=2 l=1 r=4 r-l=3 max=2 
count=2 l=2 r=5 r-l=3 max=2 
count=3 l=3 r=6 r-l=3 max=3 
count=1 l=4 r=7 r-l=3 max=3 
count=6 l=5 r=8 r-l=3 max=6
/**
 * @param {number[]} customers
 * @param {number[]} grumpy
 * @param {number} minutes
 * @return {number}
 */
var maxSatisfied = function(customers, grumpy, minutes) {
    let len = grumpy.length;
    let l = 0; let r = 0; 
    let count = 0; // Maximum customer satisfaction when the boss is not angry (at each cycle)
    let max = 0; // When the boss is not angry, the maximum number of customer satisfaction
    while (r < len) {
        if(grumpy[r] === 1) count += customers[r];    
        r++; // Always expand the window when the boss doesn't make you angry
        while(r - l > minutes) { // After the boss is not angry, narrow the window
            if(grumpy[l] === 1) count -= customers[l];
            l++;
        }
        max = Math.max(max, count); // Update the maximum number of customer satisfaction when the boss is not angry
        console.info('count='+count);
        console.info('l='+l);
        console.info('r='+r);
        console.info('r-l='+(r-l));
        console.info('max='+max);
    }
    let res = 0; // Number of customers not angry
    for (let i = 0; i < len; i++) {
        res += (grumpy[i] === 0 ? customers[i] : 0);
    }
    return res + max;
};

187. Repetitive DNA sequences

All DNA consists of A series of nucleotides abbreviated as' A ',' C ',' G 'and'T', such as "ACGAATTCCG". When studying DNA, identifying repetitive sequences in DNA can sometimes be very helpful.

Write a function to find all target substrings. The length of the target substring is 10 and appears more than once in the DNA string s.

Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
Output:["AAAAACCCCC","CCCCCAAAAA"]
{ AAAAACCCCC: 1 } l=1 r=10 
{ AAAAACCCCC: 1, AAAACCCCCA: 1 } l=2 r=11 
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1 } l=3 r=12 
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1 } l=4 r=13 
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1 } l=5 r=14 
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1 } l=6 r=15 
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1 } l=7 r=16 
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1, CCCAAAAACC: 1 } l=8 r=17 
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1, CCCAAAAACC: 1, CCAAAAACCC: 1 } l=9 r=18 
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1, CCCAAAAACC: 1, CCAAAAACCC: 1, CAAAAACCCC: 1 } l=10 r=19 
{ AAAAACCCCC: 2, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1, CCCAAAAACC: 1, CCAAAAACCC: 1, CAAAAACCCC: 1 } l=11 r=20 
{ AAAAACCCCC: 2, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ... 235 more lines
/**
 * @param {string} s
 * @return {string[]}
 */
var findRepeatedDnaSequences = function(s) {
    let map = {};
    let res = [];
    let l = 0; let r = 9; 
    while(r < s.length) {
        let temp = s.slice(l, r + 1); // Always maintain a 10 element window
        map[temp] = (map[temp] || 0) + 1;
        l++;
        r++;
        console.info(map);
        console.info('l='+l);
        console.info('r='+r);
    }
    Object.entries(map).map(([k, v] = [...item]) => {if(v > 1) res.push(k)});
    return res;
};
/**
 * @param {string} s
 * @return {string[]}
 */
var findRepeatedDnaSequences = function(s) {
    let map = new Map();
    let res = [];
    let l = 0; let r = 10;
    while(r <= s.length) {
        let temp = s.slice(l, r);
        map.set(temp, map.has(temp) ? map.get(temp) + 1 : 1);
        l++;
        r++;
    }
    for(let [k, v] of map) {
        if(v > 1) res.push(k);
    }
    return res;
};

7, leetcode - matrix

74. Search two-dimensional matrix

Write an efficient algorithm to judge whether there is a target value in m x n matrix. The matrix has the following characteristics:

The integers in each row are arranged in ascending order from left to right.

The first integer of each line is greater than the last integer of the previous line.

Input: matrix = [
                    [1, 3, 5, 7 ],
                    [10,11,16,20],
                    [23,30,34,60]
                ], target = 3
 Output: true
The search process starts from the lower left corner 23, 23 is greater than 3,
Reduce upward to 10, 10 is greater than 3,
Reduce upward to 1, 1 is less than 3,
Expand to the right to 3. 3 equals 3. End the search

23 
10 
1 
3
/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function(matrix, target) {
    let x = matrix.length - 1, y = 0;
    while(x >= 0 && y < matrix[0].length) {
        if(matrix[x][y] === target) {
            return true;
        } else if(matrix[x][y] > target) {
            x--;
        } else {
            y++;
        }
    }
    return false;
};

59. Spiral matrix II

Give you a positive integer n to generate an n x n square matrix containing all elements from 1 to n2 and the elements are spirally arranged in clockwise order.

Input: n = 3
 Output: [
        [1,2,3],
        [8,9,4],
        [7,6,5]
       ]
startX=0 startY=0 
[ [ 1, 2, null ], [ null, null, null ], [ null, null, null ] ] 1 
[ [ 1, 2, 3 ],    [ null, null, 4 ],    [ null, null, null ] ] 1 
[ [ 1, 2, 3 ],    [ null, null, 4 ],    [ null, 6, 5 ] ]       1 
[ [ 1, 2, 3 ],    [ 8, null, 4 ],       [ 7, 6, 5 ] ]          1 
=======
Input: n = 4
 Output: [
        [1,2,3,4],
        [12,13,14,5],
        [11,16,15,6],
        [10,9,8,7]
      ]
startX=0 startY=0 
[ [ 1, 2, 3, null ], [ null, null, null, null ], [ null, null, null, null ], [ null, null, null, null ] ] 1 
[ [ 1, 2, 3, 4 ], [ null, null, null, 5 ], [ null, null, null, 6 ], [ null, null, null, null ] ] 1 
[ [ 1, 2, 3, 4 ], [ null, null, null, 5 ], [ null, null, null, 6 ], [ null, 9, 8, 7 ] ] 1 
[ [ 1, 2, 3, 4 ], [ 12, null, null, 5 ], [ 11, null, null, 6 ], [ 10, 9, 8, 7 ] ] 1 
======= 
startX=1 startY=1 
[ [ 1, 2, 3, 4 ], [ 12, 13, null, 5 ], [ 11, null, null, 6 ], [ 10, 9, 8, 7 ] ] 2 
[ [ 1, 2, 3, 4 ], [ 12, 13, 14, 5 ], [ 11, null, null, 6 ], [ 10, 9, 8, 7 ] ] 2 
[ [ 1, 2, 3, 4 ], [ 12, 13, 14, 5 ], [ 11, null, 15, 6 ], [ 10, 9, 8, 7 ] ] 2 
[ [ 1, 2, 3, 4 ], [ 12, 13, 14, 5 ], [ 11, 16, 15, 6 ], [ 10, 9, 8, 7 ] ] 2 
=======
/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function(n) {
    // let res = Array.from({length: n}).map(() => new Array(n));
    let res = new Array(n).fill().map(() => new Array(n).fill(null));
    let loop = n >> 1, i = 0; //Number of cycles
    let count = 1;
    let startX = startY = 0; // Starting position 
    while(++i <= loop) {
        console.info('startX='+startX+' startY='+startY);
        // Define rows and columns
        let row = startX, column = startY;
        // [startY, n - i) fill 1, 2
        while(column < n - i) res[row][column++] = count++;
        console.info(res);
        console.info(i);
        // [startX, n - i) fill 3, 4
        while(row < n - i) res[row++][column] = count++;
        console.info(res);
        console.info(i);
        // [n - I, starty) fill 5, 6
        while(column > startY) res[row][column--] = count++; 
        console.info(res);
        console.info(i);
        // [n - I, startx) fill 7, 8
        while(row > startX) res[row--][column] = count++;
        console.info(res);
        console.info(i);
        console.info('=======');
        startX = ++startY;
    }
    if(n & 1) {// If it is an odd number, fill the center once more
        res[startX][startY] = count;
    }
    return res;
};

Press the top right, bottom left, one layer inward, traverse the matrix and fill in the grid

[ [ 1, 2, 3 ], [ null, null, null ], [ null, null, null ] ] 4 
[ [ 1, 2, 3 ], [ null, null, 4 ], [ null, null, 5 ] ] 6 
[ [ 1, 2, 3 ], [ null, null, 4 ], [ 7, 6, 5 ] ] 8 
[ [ 1, 2, 3 ], [ 8, null, 4 ], [ 7, 6, 5 ] ] 9 
======= 
[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 10 
[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 10 
[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 10 
[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 10 
=======
[ [ 1, 2, 3, 4 ], [ null, null, null, null ], [ null, null, null, null ], [ null, null, null, null ] ] 5 
[ [ 1, 2, 3, 4 ], [ null, null, null, 5 ], [ null, null, null, 6 ], [ null, null, null, 7 ] ] 8 
[ [ 1, 2, 3, 4 ], [ null, null, null, 5 ], [ null, null, null, 6 ], [ 10, 9, 8, 7 ] ] 11 
[ [ 1, 2, 3, 4 ], [ 12, null, null, 5 ], [ 11, null, null, 6 ], [ 10, 9, 8, 7 ] ] 13 
======= 
[ [ 1, 2, 3, 4 ], [ 12, 13, 14, 5 ], [ 11, null, null, 6 ], [ 10, 9, 8, 7 ] ] 15 
[ [ 1, 2, 3, 4 ], [ 12, 13, 14, 5 ], [ 11, null, 15, 6 ], [ 10, 9, 8, 7 ] ] 16 
[ [ 1, 2, 3, 4 ], [ 12, 13, 14, 5 ], [ 11, 16, 15, 6 ], [ 10, 9, 8, 7 ] ] 17 
[ [ 1, 2, 3, 4 ], [ 12, 13, 14, 5 ], [ 11, 16, 15, 6 ], [ 10, 9, 8, 7 ] ] 17 
=======
var generateMatrix = function (n) {
    let matrix = new Array(n).fill().map(() => new Array(n).fill(null));
    let num = 1;
    let left = 0, right = n - 1, top = 0, bottom = n - 1;
    while (num <= n * n) {
        // From left to right
        for (let i = left; i <= right; i++) matrix[top][i] = num++; 
        console.info(matrix);
        console.info(num);
        top++;
        // From top to bottom
        for (let i = top; i <= bottom; i++) matrix[i][right] = num++;
        console.info(matrix);
        console.info(num);
        right--;
        // Right to left
        for (let i = right; i >= left; i--) matrix[bottom][i] = num++;
        console.info(matrix);
        console.info(num);
        bottom--;
        // From bottom to top
        for (let i = bottom; i >= top; i--) matrix[i][left] = num++;
        console.info(matrix);
        console.info(num);
        left++;
        console.info('=======');
    }
    return matrix;
};

8, leetcode - stack and queue

20. Valid brackets

Given a string s that only includes' (',') ',' {','} ',' [','] ', judge whether the string is valid.

Valid strings must meet:

The left parenthesis must be closed with the same type of right parenthesis.
The left parentheses must be closed in the correct order.

Input: s = "()[]{}"
Output: true
[ '(' ] 
[] 
[ '[' ] 
[] 
[ '{' ] 
[]
/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
    let map  = {'{':'}','(':')','[':']'};
    let stack = [];
    for(let i of s){
        if(map[i]){
            stack.push(i);
        }else{
            if(map[stack[stack.length - 1]] === i){
                stack.pop();
            }else{
                return false;
            }
        }
        console.info(stack);
    }
    return stack.length === 0;
};

155. Minimum stack

Input:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

Output:
[null,null,null,null,-3,null,0,-2]

Explanation:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> return -3.
minStack.pop();
minStack.top();      --> Return 0.
minStack.getMin();   --> return -2.
Minimum stack print result:
[ -2 ] 
[ -2, -2 ] 
[ -2, -2, -3 ]
/**
 * initialize your data structure here.
 */
var MinStack = function() {
    this.stack = [];
    this.minStack = [];
};

/** 
 * @param {number} val
 * @return {void}
 */
MinStack.prototype.push = function(val) {
    this.stack.push(val);
    let topOfMinStack = this.minStack[this.minStack.length - 1];
    if(this.minStack.length === 0 || val < topOfMinStack){
        this.minStack.push(val);
    } else {
        this.minStack.push(topOfMinStack);
    }
    console.info(this.minStack);
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
    this.stack.pop();
    this.minStack.pop();
};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
    return this.stack[this.stack.length - 1];
};

/**
 * @return {number}
 */
MinStack.prototype.getMin = function() {
    return this.minStack[this.minStack.length - 1];
};

/**
 * Your MinStack object will be instantiated and called as such:
 * var obj = new MinStack()
 * obj.push(val)
 * obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.getMin()
 */

739. Daily temperature

According to the daily temperature list temperatures, please calculate how many days you need to wait for a higher temperature every day. If the temperature will not rise after that, please replace it with 0 at this position.

input: temperatures = [73,74,75,71,69,72,76,73]
output: [1,1,4,2,1,1,0,0]
Out of stack     stack Value of      stack       res
        [ 73 ]         [ 0 ]       [ 0, 0, 0, 0, 0, 0, 0, 0 ] 
1-0     [ 74 ]         [ 1 ]       [ 1, 0, 0, 0, 0, 0, 0, 0 ] 
2-1     [ 75 ]         [ 2 ]       [ 1, 1, 0, 0, 0, 0, 0, 0 ] 
        [ 75, 71 ]     [ 2, 3 ]    [ 1, 1, 0, 0, 0, 0, 0, 0 ] 
        [ 75, 71, 69 ] [ 2, 3, 4 ] [ 1, 1, 0, 0, 0, 0, 0, 0 ] 
5-4 5-3 [ 75, 72 ]     [ 2, 5 ]    [ 1, 1, 0, 2, 1, 0, 0, 0 ] 
6-5 6-2 [ 76 ]         [ 6 ]       [ 1, 1, 4, 2, 1, 1, 0, 0 ] 
        [ 76, 73 ]     [ 6, 7 ]    [ 1, 1, 4, 2, 1, 1, 0, 0 ]
/**
 * @param {number[]} temperatures
 * @return {number[]}
 */
var dailyTemperatures = function(temperatures) {
    let len = temperatures.length;
    let res = (new Array(len)).fill(0);
    let stack = [];
    for(let i = 0; i < len; i++) {
        while(stack.length && temperatures[i] > temperatures[stack[stack.length - 1]]) {
            let top = stack.pop();
            console.info(i + '-' + top);
            // The current subscript subtracts the subscript of the previous record
            res[top] = i - top;
        }
        stack.push(i);
        stack1.push(temperatures[i]);
        console.info(stack);
        console.info(res);
    }
    return res;
};

232. Implement queue with stack

The stack first in first out method is used to achieve the effect of queue first in first out

Please use only two stacks to implement the FIFO queue. The queue should support all the operations supported by the general queue (push, pop, peek, empty):

Implement MyQueue class:

void push(int x) pushes element X to the end of the queue
int pop() removes the element from the beginning of the queue and returns it
int peek() returns the element at the beginning of the queue
boolean empty() returns true if the queue is empty; otherwise, returns false

explain:

You can only use standard stack operations -- that is, only push to top, peek/pop from top, size, and is empty operations are legal.
Your language may not support stack. You can use list or deque (double ended queue) to simulate a stack, as long as it is a standard stack operation.

Input:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
Output:
[null, null, null, 1, 1, false]

Explanation:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
var MyQueue = function() {
    this.stack1 = []; // For joining the team
    this.stack2 = []; // Used to get out of the team
};

/** 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function(x) {
    this.stack1.push(x);
};

/**
 * @return {number}
 */
MyQueue.prototype.pop = function() {
    // Import the data in the queue stack into the queue stack
    if(!this.stack2.length) {
        while(this.stack1.length) {
            this.stack2.push(this.stack1.pop());
        }
    }
    return this.stack2.pop();
};

/**
 * @return {number}
 */
MyQueue.prototype.peek = function() {
    if(!this.stack2.length) {
        while(this.stack1.length) {
            this.stack2.push(this.stack1.pop());
        }
    }
    // Compared with pop, it's just not out of the team
    return this.stack2[this.stack2.length - 1];
};

/**
 * @return {boolean}
 */
MyQueue.prototype.empty = function() {
    // When both the inbound and outbound stacks are empty, the queue is empty
    return !this.stack1.length && !this.stack2.length;
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * var obj = new MyQueue()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.peek()
 * var param_4 = obj.empty()
 */

225. Implement stack with queue

Queue FIFO is used to realize the stack FIFO effect

When a queue simulates the pop-up elements of the stack, just add the elements at the head of the queue (except the last element) to the end of the queue. At this time, the pop-up elements are the order of the stack.

Please use only two queues to implement a last in first out (LIFO) stack, and support all four operations of the ordinary stack (push, top, pop and empty).

Implement MyStack class:

void push(int x) pushes element X to the top of the stack.
int pop() removes and returns the top of stack element.
int top() returns the stack top element.
boolean empty() returns true if the stack is empty; otherwise, returns false.

be careful:

You can only use the basic operations of the queue -- that is, push to back, peek/pop from front, size and is empty.
Your language may not support queues. You can use list or deque to simulate a queue, as long as it is a standard queue operation.

Input:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
Output:
[null, null, null, 2, 2, false]

Explanation:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // Return 2
myStack.pop(); // Return 2
myStack.empty(); // Return False
/**
 * Initialize your data structure here.
 */
var MyStack = function() {
    this.queue = [];
};

/**
 * Push element x onto stack. 
 * @param {number} x
 * @return {void}
 */
MyStack.prototype.push = function(x) {
    this.queue.push(x);
};

/**
 * Removes the element on top of the stack and returns that element.
 * @return {number}
 */
MyStack.prototype.pop = function() {
    let size = this.queue.length;
    while(size-- > 1) {
        this.queue.push(this.queue.shift());
    }
    return this.queue.shift();
};

/**
 * Get the top element.
 * @return {number}
 */
MyStack.prototype.top = function() {
    const x = this.pop();
    this.queue.push(x);
    return x;
};

/**
 * Returns whether the stack is empty.
 * @return {boolean}
 */
MyStack.prototype.empty = function() {
    return !this.queue.length;
};

/**
 * Your MyStack object will be instantiated and called as such:
 * var obj = new MyStack()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.empty()
 */

239. Maximum value of sliding window

Give you an integer array nums. There is a sliding window with a size of K moving from the leftmost side of the array to the rightmost side of the array. You can only see k numbers in the sliding window. The sliding window moves only one bit to the right at a time.

Returns the maximum value in the sliding window.

Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
 Output:[3,3,5,5,6,7]
Explanation:
Position of sliding window                Maximum
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7
The window initially expands from 0 to k Since then, it has been maintained k Move back step by step until you can't move
i+1>=k   window      window Corresponding nums value
f        [ 0 ]       [ 1 ] 
f        [ 1 ]       [ 3 ] 
t        [ 1, 2 ]    [ 3, -1 ] 
t        [ 1, 2, 3 ] [ 3, -1, -3 ] 
t        [ 4 ]       [ 5 ] 
t        [ 4, 5 ]    [ 5, 3 ] 
t        [ 6 ]       [ 6 ] 
t        [ 7 ]       [ 7 ]
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function(nums, k) {    
    let window = [];
    let res = [];
    for(let i = 0; i < nums.length; i++) {
        // Kick out the outside of the sliding window first
        if(window[0] !== undefined && window[0] <= i - k) window.shift();
        // Make sure the team leader is the biggest
        while(nums[window[window.length - 1]] <= nums[i])  window.pop();
        window.push(i);
        if(i + 1 >= k) res.push(nums[window[0]]);
        console.info(window);
    }
    return res;
};

9, leetcode - linked list

237. Delete nodes in the linked list

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.
/**
 * 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) {
    node.val = node.next.val;
    node.next = node.next.next;
};

Sword finger Offer 18. Delete the node of the linked list

input: head = [4,5,1,9], val = 5
 output: [4,1,9]
explain: 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.
/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} val
 * @return {ListNode}
 */
var deleteNode = function(head, val) {
    let dummpy = new ListNode();
    dummpy.next = head;
    let cur = dummpy;
    while(cur.next){
        if(cur.next.val === val) {
            cur.next = cur.next.next;
            break;
        }
        cur = cur.next;
    }
    return dummpy.next;
};

160. Intersecting linked list

Here are the head nodes headA and headB of the two single linked lists. Please find out and return the starting node where the two single linked lists intersect. If the two linked lists have no intersection, return null.

/**
 * 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 curA = headA;
    let curB = headB;
    while(curA !== curB) {
        curA = curA === null ? headB : curA.next;
        curB = curB === null ? headA : curB.next;
    }
    return curA;
};

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.

Input: head = [1,2,3,4,5], n = 2
 Output: [1,2,3,5]
/**
    * 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 dummy = new ListNode();
        dummy.next = head;
        let slow = dummy;
        let fast = dummy;
        while(n !== 0) {
            fast = fast.next;
            n--;
        }
        while(fast.next) {
            slow = slow.next;
            fast = fast.next;
        }
        slow.next = slow.next.next;
        return dummy.next;
    };

21. Merge two ordered linked lists

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

Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]
/**
 * 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) {
    const dummpy = new ListNode();
    let cur = dummpy;
    while(l1 && l2) {
        if(l1.val > l2.val) {
            cur.next = l2;
            l2 = l2.next;
        } else {
            cur.next = l1;
            l1 = l1.next;
        }
        cur = cur.next;
    }
    cur.next = l1 ? l1 : l2;
    return dummpy.next;
};

876. Intermediate node of linked list

Given a non empty single linked list with head node, return the intermediate node of the linked list.

If there are two intermediate nodes, the second intermediate node is returned.

/**
 * 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 middleNode = function(head) {
    let slow = head;
    let fast = head;
    while(fast && fast.next) {
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow;
};

206. Reverse linked list

Give you the head node of the single linked list. Please reverse the linked list and return the reversed linked list.

Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]
/**
 * 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 pre = null;
    let cur = head;
    while(cur){
        let temp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;
};

328. Parity linked list

Given a single linked list, all odd nodes and even nodes are arranged together. Please note that odd nodes and even nodes here refer to the parity of node numbers, not the parity of node values.

input: 1->2->3->4->5->NULL
 output: 1->3->5->2->4->NULL
/**
 * 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 head;
    let odd = head;
    let even = head.next;
    let evenStart = even;
    while(even && even.next) {
        odd.next = even.next;
        odd = odd.next;
        even.next = odd.next;
        even = even.next;
    }
    odd.next = evenStart;
    return head;
};

10, leetcode - binary tree

144. Preorder traversal of binary tree

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    let res = [];
    const dfs = (root) => {
        if(!root) return;
        res.push(root.val);
        dfs(root.left);
        dfs(root.right);
    }
    dfs(root);
    return res;
};

94. Middle order traversal of binary tree

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function(root) {
    let res = [];
    const dfs = (root) => {
        if(!root) return;
        dfs(root.left);
        res.push(root.val);
        dfs(root.right);
    }
    dfs(root);
    return res;
};

145. Post order traversal of binary tree

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function(root) {
    let res = [];
    const dfs = (root) => {
        if(!root) return;
        dfs(root.left);
        dfs(root.right);
        res.push(root.val);
    }
    dfs(root);
    return res;
};

Sword finger Offer 07. Rebuild binary tree

Enter the results of preorder traversal and inorder traversal of a binary tree, please build the binary tree and return its root node.

It is assumed that the input pre order traversal and middle order traversal results do not contain duplicate numbers.

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {number[]} preorder
 * @param {number[]} inorder
 * @return {TreeNode}
 */
var buildTree = function(preorder, inorder) {
    if (!preorder.length || !inorder.length) {
        return null;
    }

    const rootVal = preorder[0];
    const node = new TreeNode(rootVal);

    let i = inorder.indexOf(rootVal);
    node.left = buildTree(preorder.slice(1, i + 1), inorder.slice(0, i));
    node.right = buildTree(preorder.slice(i + 1), inorder.slice(i + 1));
    return node;
};

102. Sequence traversal of binary tree

That is, all nodes are accessed layer by layer from left to right

Binary tree:[3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7
 Return its sequence traversal result:

[
  [3],
  [9,20],
  [15,7]
]
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
  if(!root) return [];
  let res = [];
  let queue = [];
  queue.push(root);
  while(queue.length) {
      let len = queue.length;
      let cur = [];
      while(len--) {
          let temp = queue.shift();
          cur.push(temp.val);
          if(temp.left) queue.push(temp.left);
          if(temp.right) queue.push(temp.right);
      }
      res.push(cur);
  } 
  return res;
}

103. Zigzag sequence traversal of binary tree

That is, traverse the next layer from left to right, and then from right to left

Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7
 The zigzag sequence traversal is returned as follows:

[
  [3],
  [20,9],
  [15,7]
]
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var zigzagLevelOrder = function (root) {
    if(!root) return [];
    let res = [];
    let queue = [];
    queue.push(root);
    while(queue.length) {
        let len = queue.length;
        let cur = [];
        while(len--) {
            let temp = queue.shift();
            cur.push(temp.val);
            if(temp.left) queue.push(temp.left);
            if(temp.right) queue.push(temp.right);
        }
        res.length % 2 === 0 ? res.push(cur) : res.push(cur.reverse());
    }

    return res;
};

589. Preorder traversal of n-ary tree

Input: root = [1,null,3,2,4,null,5,6]
Output: [1,3,5,6,2,4]
/**
 * // Definition for a Node.
 * function Node(val,children) {
 *    this.val = val;
 *    this.children = children;
 * };
 */
 
/**
 * @param {Node|null} root
 * @return {number[]}
 */
var preorder = function(root) {
    let res = [];
    const dfs = (root) => {
        if(!root) return;
        res.push(root.val);
        for(let i = 0; i < root.children.length; i++) {
            dfs(root.children[i]);
        }
    }
    dfs(root);
    return res;
};

590. Post order traversal of n-ary tree

Input: root = [1,null,3,2,4,null,5,6]
Output: [5,6,3,2,4,1]
/**
 * // Definition for a Node.
 * function Node(val,children) {
 *    this.val = val;
 *    this.children = children;
 * };
 */

/**
 * @param {Node|null} root
 * @return {number[]}
 */
var postorder = function(root) {
    let res = [];
    const dfs = (root) => {
        if(!root) return;
        for(let i = 0; i < root.children.length; i++) {
            dfs(root.children[i]);
        }
        res.push(root.val);
    }
    dfs(root);
    return res;
};

101. Symmetric binary tree

Use recursion to compare from top to bottom and return the comparison results.

Given a binary tree, check whether it is mirror symmetric.

Binary tree [1,2,2,3,4,4,3] It's symmetrical.
    1
   / \
  2   2
 / \ / \
3  4 4  3
 But the following one [1,2,2,null,3,null,3] Is not mirror symmetric:
    1
   / \
  2   2
   \   \
   3    3
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isSymmetric = function(root) {
    if(!root) return true;
    const dfs = (left, right) => {
        if(!left && !right) return true;
        if(!left || !right || right.val !== left.val) return false;
        return dfs(left.left, right.right) && dfs(left.right, right.left);
    }
    return dfs(root.left, root.right);
};

226. Flip binary tree

Use recursion to flip from top to bottom and return the flipped results.

Input:
     4
   /   \
  2     7
 / \   / \
1   3 6   9
 Output:
     4
   /   \
  7     2
 / \   / \
9   6 3   1
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var invertTree = function(root) {
    const dfs = (root) => {
        if(!root) return root;
        let temp = root.left;
        root.left = root.right;
        root.right = temp;
        dfs(root.left);
        dfs(root.right);
        return root;
    }
    return dfs(root);
};

617. Merge binary tree

input: 
	Tree 1                     Tree 2                  
          1                         2                             
         / \                       / \                            
        3   2                     1   3                        
       /                           \   \                      
      5                             4   7                  
output: 
Merged tree:
	     3
	    / \
	   4   5
	  / \   \ 
	 5   4   7
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root1
 * @param {TreeNode} root2
 * @return {TreeNode}
 */
var mergeTrees = function(root1, root2) {
    const dfs = (root1, root2) => {
        if(root1 === null && root2) return root2;
        if((root1 && root2 === null) || (root1 === null && root2 === null)) return root1;
        let root = new TreeNode(root1.val + root2.val);
        root.left = dfs(root1.left, root2.left);
        root.right = dfs(root1.right, root2.right);
        return root;
    }
    return dfs(root1, root2);
};

110. Balanced binary tree

Balanced binary tree is defined as: the absolute value of the height difference between the left and right subtrees of each node of a binary tree does not exceed 1.

Input: root = [3,9,20,null,null,15,7]
Output: true
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isBalanced = function(root) {
    let res = true;
    const dfs = (root) => {
        if(!root) return 0;
        let left = dfs(root.left);
        let right = dfs(root.right);
        if(Math.abs(left - right) > 1) res = false;
        return Math.max(left, right) + 1;
    }
    dfs(root);
    return res;
};

104. Maximum depth of binary tree

The depth of the binary tree is the number of nodes on the longest path from the root node to the farthest leaf node.

Note: leaf nodes refer to nodes without child nodes.

Given binary tree [3,9,20,null,null,15,7],
    3
   / \
  9  20
    /  \
   15   7
 Returns its maximum depth 3.
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
    const dfs = (root) => {
        if(!root) return 0;
        return Math.max(dfs(root.left), dfs(root.right))+1;
    }
    return dfs(root);
};

111. Minimum depth of binary tree

The minimum depth is the number of nodes on the shortest path from the root node to the nearest leaf node.

Note: leaf nodes refer to nodes without child nodes.

Input: root = [3,9,20,null,null,15,7]
Output: 2
/**
 * @param {TreeNode} root
 * @return {number}
 */
var minDepth = function(root) {
    const dfs = (root) => {
        if(!root) return 0;
        if(!root.left) return dfs(root.right) + 1;
        if(!root.right) return dfs(root.left) + 1;
        return Math.min(dfs(root.left), dfs(root.right)) + 1;
    }
    return dfs(root);
};

563. Slope of binary tree

The slope of a tree node is defined as the absolute value of the difference between the sum of the nodes of the left subtree and the sum of the nodes of the right subtree. If there is no left subtree, the sum of nodes of the left subtree is 0; The same is true without a right subtree. The slope of the empty node is 0.

The slope of the whole tree is the sum of the slopes of all its nodes.

Input: root = [4,2,9,3,5,null,7]
Output: 15
 Explanation:
Slope of node 3:|0-0| = 0((no child nodes)
Slope of node 5:|0-0| = 0((no child nodes)
Slope of node 7:|0-0| = 0((no child nodes)
Slope of node 2:|3-5| = 2(The left subtree is the left child node, so the sum is 3; The right subtree is the right child node, so the sum is 5)
Slope of node 9:|0-7| = 7(There is no left subtree, so sum is 0; The right subtree is exactly the right child node, so sum is 7)
Slope of node 4:|(3+5+2)-(9+7)| = |10-16| = 6(The left subtree values are 3, 5 and 2, and are 10; Right subtree values are 9 and 7, and are 16)
Slope sum: 0 + 0 + 0 + 2 + 7 + 6 = 15
/**
 * @param {TreeNode} root
 * @return {number}
 */
var findTilt = function(root) {
    let res = 0;
    const dfs = (root) => {
        if(!root) return 0;
        let left = dfs(root.left);
        let right = dfs(root.right);
        res += Math.abs(left - right);
        return left + right + root.val;
    }
    dfs(root);
    return res;
};

98. Validate binary search tree

A valid binary search tree is defined as follows:

  • The left subtree of a node contains only a number smaller than the current node.
  • The right subtree of a node contains only a number greater than the current node.
  • All left and right subtrees themselves must also be binary search trees.
Input: root = [2,1,3]
Output: true
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isValidBST = function (root) {
    const dfs = (root, min, max) => {
        if(!root) return true;
        if(root.val >= max || root.val <= min) return false;
        return dfs(root.left, min, root.val) && dfs(root.right, root.val, max);
    }
    return dfs(root, -Infinity, Infinity);
};

112. Path sum

Give you the root node root of the binary tree and an integer targetSum representing the target sum. Judge whether there is a path from the root node to the leaf node in the tree. The sum of all node values on this path is equal to the target and targetSum.

A leaf node is a node that has no children.

Input: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
 Output: true
/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {boolean}
 */
var hasPathSum = function(root, targetSum) {
    let res = false;
    const dfs = (root, sum) => {
        if(res || !root) return;
        sum += root.val;
        if(!root.left && !root.right) {
            if(sum === targetSum) res = true;
            return;
        }
        if(root.left) dfs(root.left, sum);
        if(root.right) dfs(root.right, sum);
    }
    dfs(root, 0);
    return res;
};

113. Path sum II

Give you the root node of the binary tree root and an integer target and targetSum, and find all the paths from the root node to the leaf node whose total path is equal to the given target sum.

A leaf node is a node that has no children.

Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
 Output:[[5,4,11,2],[5,8,4,5]]
/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {number[][]}
 */
var pathSum = function(root, targetSum) {
    let res = [];
    const dfs = (root, sum, path) => {
        if(!root) {
            return;
        }
        sum += root.val;
        path.push(root.val);
        if(!root.left && !root.right) {
            if(sum === targetSum) res.push(path.slice());
        }
        if(root.left) dfs(root.left, sum, path);
        if(root.right) dfs(root.right, sum, path);
        path.pop();
    }
    dfs(root, 0, []);
    return res;
};

11, leetcode - join search set

695. Maximum area of the island

Give you a binary matrix grid of size m x n.

An island is a combination of some adjacent 1s (representing land). The "adjacent" here requires that two 1s must be adjacent in four horizontal or vertical directions. You can assume that the four edges of the grid are surrounded by 0 (representing water).

The area of an island is the number of cells on the island with a value of 1.

Calculate and return the largest island area in the grid. If there are no islands, the return area is 0.

Input: grid = [
[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]
]
Output: 6
 Explanation: the answer should not be 11, because the island can only contain 1 in the horizontal or vertical directions.
/**
 * @param {number[][]} grid
 * @return {number}
 */
var maxAreaOfIsland = function (grid) {
  let row = grid.length; let col = grid[0].length;
  let res = 0;
  const dfs = (i, j) => {
    // Subscript out of bounds returns 0
    if (i < 0 || i >= row || j < 0 || j >= col) return 0;
    // A value of 0 returns 0
    if (grid[i][j] === 0) return 0;
    // Set to 0 after access to prevent repeated access
    grid[i][j] = 0;
    // Recursive calculation of island area
    return 1 + dfs(i, j - 1) + dfs(i - 1, j) + dfs(i, j + 1) + dfs(i + 1, j);
  };
  // Traversing a two-dimensional array
  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
      if (grid[i][j] === 1) {
        res = Math.max(res, dfs(i, j));
      } else {
        continue;
      }
    }
  }
  return res;
};

200. Number of islands

Give you a two-dimensional grid composed of '1' (land) and '0' (water). Please calculate the number of islands in the grid.

Islands are always surrounded by water, and each island can only be formed by adjacent land connections in the horizontal and / or vertical direction.

In addition, you can assume that all four sides of the mesh are surrounded by water.

Input: grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
Output: 1
/**
 * @param {character[][]} grid
 * @return {number}
 */
var numIslands = function (grid) {
  let row = grid.length; let col = grid[0].length;
  let res = 0;
  const dfs = (i, j) => {
    // Subscript out of bounds returns 0
    if (i < 0 || i >= row || j < 0 || j >= col) return '0';
    // A value of 0 returns 0
    if (grid[i][j] === '0') return '0';
    // Set to 0 after access to prevent repeated access
    grid[i][j] = '0';
    dfs(i, j - 1);
    dfs(i - 1, j);
    dfs(i, j + 1);
    dfs(i + 1, j);
  };
  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
      if (grid[i][j] === '1') {
        dfs(i, j);
        res++;
      }
    }
  }
  return res;
};

12, leetcode - backtracking

46. Full arrangement No duplicate numbers

Given an array num without duplicate numbers, returns all possible permutations. You can return answers in any order.

Input: nums = [1,2,3]
Output: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
[ 1 ] 
[ 1, 2 ] 
[ 1, 2, 3 ] 
[ 1, 3 ] 
[ 1, 3, 2 ] 
[ 2 ] 
[ 2, 1 ] 
[ 2, 1, 3 ] 
[ 2, 3 ] 
[ 2, 3, 1 ] 
[ 3 ] 
[ 3, 1 ] 
[ 3, 1, 2 ] 
[ 3, 2 ] 
[ 3, 2, 1 ]
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var permute = function(nums) {
    const res = [];
    const used = {};
    function dfs(path) {
        if(path.length === nums.length){
            res.push(path.slice());
            return res;
        }
        for(let i = 0; i < nums.length; i++) { // Transverse circulation
            if(used[i]) continue; // Remove used numbers during vertical recursion
            path.push(nums[i]);
            used[i] = true;
            console.info(path);
            dfs(path); // Vertical recursion
            path.pop();
            used[i] = false;
        }
    }
    dfs([]); 
    return res;
};

47. Full arrangement II Contains duplicate numbers

Given a sequence nums that can contain repeated numbers, return all non repeated full permutations in any order.

Input: nums = [1,1,2]
Output: [ [1,1,2], [1,2,1], [2,1,1] ]
Filter out the horizontal duplicates of the same layer before recursion of the first layer (this is recommended, and the second branch is directly removed)
This belongs to pruning directly from the root
!used[i-1]Namely used[i - 1] == false,Describe the same tree layer nums[i - 1]Used

[ 1 ] 
[ 1, 1 ] 
[ 1, 1, 2 ] 
[ 1, 2 ] 
[ 1, 2, 1 ] 
[ 2 ] 
[ 2, 1 ] 
[ 2, 1, 1 ]
Filter out the repetition of horizontal same layer in vertical recursion
 This belongs to deep pruning from branches and leaves one by one, and the efficiency is not as good as pruning from roots. It is also difficult to understand
used[i-1]Namely used[i - 1] == true,Describe the same tree branch nums[i - 1]Used

[ 1 ] 
[ 1, 2 ] 
[ 1 ] 
[ 1, 1 ] 
[ 1, 1, 2 ] 
[ 1, 2 ] 
[ 1, 2, 1 ] 
[ 2 ] 
[ 2, 1 ] 
[ 2, 1 ] 
[ 2, 1, 1 ]
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var permuteUnique = function(nums) {
    let res = [];
    let used = {};
    // Sort first to filter duplicate numbers
    nums.sort((a,b)=>a-b); 
    const dfs = (path) => {
        if(path.length === nums.length){
            res.push(path.slice());
            return res;
        }
        for(let i = 0; i < nums.length; i++) {
            if(used[i]) continue;
            // Filter out horizontal duplicates of the same layer before recursion of the first layer (recommended)
            if(i>0 && nums[i] === nums[i-1] && !used[i-1]) continue;
            // if(i-1>=0 && nums[i] === nums[i-1] && !used[i-1]) continue;
            // Filter out the repetition of horizontal same layer in vertical recursion
            // if(i-1>=0 && nums[i] === nums[i-1] && used[i-1]) continue;
            path.push(nums[i]);
            console.info(path);
            used[i] = true;
            dfs(path);
            path.pop();
            used[i] = false;
        }
    }
    dfs([]);
    return res;
};

39. Combination sum

An array without duplicate numbers. The numbers in the array can be reused without restriction

Given a positive integer array of candidates without duplicate elements and a positive integer target, find all the unique combinations in candidates that can make the number and target the target number.

The number in candidates can be selected repeatedly without limit. If the number of at least one selected number is different, the two combinations are unique.

For a given input, the number of unique combinations of guaranteed sum and target is less than 150.

input: candidates = [2,3,6,7], target = 7
 output: [ [7], [2,2,3] ]
[ 2 ] 
[ 2, 2 ] 
[ 2, 2, 2 ] 
[ 2, 2, 2, 2 ] 
[ 2, 2, 2, 3 ] 
[ 2, 2, 2, 6 ] 
[ 2, 2, 2, 7 ] 
[ 2, 2, 3 ] 
[ 2, 2, 6 ] 
[ 2, 2, 7 ] 
[ 2, 3 ] 
[ 2, 3, 3 ] 
[ 2, 3, 6 ] 
[ 2, 3, 7 ] 
[ 2, 6 ] 
[ 2, 7 ] 
[ 3 ] 
[ 3, 3 ] 
[ 3, 3, 3 ] 
[ 3, 3, 6 ] 
[ 3, 3, 7 ] 
[ 3, 6 ] 
[ 3, 7 ] 
[ 6 ] 
[ 6, 6 ] 
[ 6, 7 ] 
[ 7 ]
/**
 * @param {number[]} candidates
 * @param {number} target
 * @return {number[][]}
 */
var combinationSum = function(candidates, target) {
    let res = [];
    const dfs = (start, temp, sum) => {
        if(sum >= target){
            if(sum === target){
                res.push(temp.slice());
            }
            return;
        }
        for(let i = start; i < candidates.length; i++){
            temp.push(candidates[i]);
            dfs(i, temp, sum + candidates[i]);
            temp.pop();
        }
    }
    dfs(0,[],0);
    return res;
};

40. Combined sum II

An array containing duplicate numbers that can only be used once in each combination

It needs to be understood that what we need to redo is the "used" on the same tree layer, and the elements on the same branch are all elements in the same combination, so we don't need to redo.

Given an array of candidates and a target number target, find out all combinations in candidates that can make the sum of numbers target.

Each number in candidates can only be used once in each combination.

Note: the solution set cannot contain duplicate combinations.

input: candidates = [2,3,6,7], target = 7
 output: [ [7] ]
dfs(i + 1, temp, sum + candidates[i]);Statement
i+1 ensure candidates Each number in can only be used once in each combination

[ 2 ] 
[ 2, 3 ] 
[ 2, 3, 6 ] 
[ 2, 3, 7 ] 
[ 2, 6 ] 
[ 2, 7 ] 
[ 3 ] 
[ 3, 6 ] 
[ 3, 7 ] 
[ 6 ] 
[ 6, 7 ] 
[ 7 ]
input: candidates = [2,5,2,1,2], target = 5,
output: [ [1,2,2], [5] ]
You need to sort first:[1,2,2,2,5]

Do not remove horizontal same layer duplicates
[ 1 ] [ 1, 2 ] [ 1, 2, 2 ] [ 1, 2, 2 ] [ 1, 2, 5 ] 
[ 1, 2 ] [ 1, 2, 2 ] [ 1, 2, 5 ] 
[ 1, 2 ] [ 1, 2, 5 ] [ 1, 5 ] 
[ 2 ] [ 2, 2 ] [ 2, 2, 2 ] [ 2, 2, 5 ] [ 2, 2 ] [ 2, 2, 5 ] [ 2, 5 ] 
[ 2 ] [ 2, 2 ] [ 2, 2, 5 ] [ 2, 5 ] 
[ 2 ] [ 2, 5 ] 
[ 5 ]

Remove horizontal same layer duplicates
[ 1 ] [ 1, 2 ] [ 1, 2, 2 ] [ 1, 2, 5 ] [ 1, 5 ] 
[ 2 ] [ 2, 2 ] [ 2, 2, 2 ] [ 2, 2, 5 ] [ 2, 5 ] 
[ 5 ]
/**
 * @param {number[]} candidates
 * @param {number} target
 * @return {number[][]}
 */
var combinationSum2 = function(candidates, target) {
    let res = [];
    candidates.sort((a, b) => a - b);
    const dfs = (start,temp,sum) => {
        // When the sum is greater than or equal to the target value, the subsequent branches can no longer meet the result conditions, and pruning returns
        if(sum >= target){
            // When the sum is equal to the target value, the target value is recorded
            if(sum === target){
                res.push(temp.slice());
            }
            return;
        }
        for(let i = start; i < candidates.length; i++){
            // Remove horizontal same layer duplicates
            if(i > start && candidates[i] === candidates[i-1]) continue;
            temp.push(candidates[i]);
            // i+1 ensures that each number in candidates can only be used once in each combination
            dfs(i + 1, temp, sum + candidates[i]);
            temp.pop();
        }
    }
    dfs(0,[],0);
    return res;
};

216. Combined sum III

The range is [1, 9], the fixed length of each combination is k, and the target is n

Find the combination of all k numbers whose sum is n. Only positive integers of 1 - 9 are allowed in the combination, and there are no duplicate numbers in each combination.

explain:

All numbers are positive integers.
The solution set cannot contain duplicate combinations.

input: k = 2, n = 7
 output: [[1,6],[2,5],[3,4]]
The current has not been pruned, and all combinations have been printed. Pruning to be updated...

[ 1 ] [ 1, 2 ] [ 1, 3 ] [ 1, 4 ] [ 1, 5 ] [ 1, 6 ] [ 1, 7 ] [ 1, 8 ] [ 1, 9 ] 
[ 2 ] [ 2, 3 ] [ 2, 4 ] [ 2, 5 ] [ 2, 6 ] [ 2, 7 ] [ 2, 8 ] [ 2, 9 ] 
[ 3 ] [ 3, 4 ] [ 3, 5 ] [ 3, 6 ] [ 3, 7 ] [ 3, 8 ] [ 3, 9 ] 
[ 4 ] [ 4, 5 ] [ 4, 6 ] [ 4, 7 ] [ 4, 8 ] [ 4, 9 ] 
[ 5 ] [ 5, 6 ] [ 5, 7 ] [ 5, 8 ] [ 5, 9 ] 
[ 6 ] [ 6, 7 ] [ 6, 8 ] [ 6, 9 ] 
[ 7 ] [ 7, 8 ] [ 7, 9 ] 
[ 8 ] [ 8, 9 ] 
[ 9 ]
/**
 * @param {number} k
 * @param {number} n
 * @return {number[][]}
 */
var combinationSum3 = function(k, n) {
    let res = [];
    const dfs = (start,temp,sum) => {
        if(temp.length === k) {
            if(sum === n) {
                res.push(temp.slice());
            }
            return;
        }
        for(let i = start; i <= 9; i++){
            temp.push(i);
            console.info(temp);
            // Sum does not directly change the value of sum itself here, so - i operation is not required after dfs
            dfs(i + 1,temp,sum + i);
            temp.pop();
        }
    }
    // 1 is a value, not a subscript
    dfs(1,[],0);
    return res;
};

77. Portfolio

The range is [1, n], and the fixed length of each combination is k

Given two integers n and k, returns the combination of all possible k numbers in the range [1, n].

You can return answers in any order.

Input: n = 4, k = 2
 Output: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
[ 1 ] 
[ 1, 2 ] 
[ 1, 3 ] 
[ 1, 4 ] 
[ 2 ] 
[ 2, 3 ] 
[ 2, 4 ] 
[ 3 ] 
[ 3, 4 ] 
[ 4 ]
/**
 * @param {number} n
 * @param {number} k
 * @return {number[][]}
 */
var combine = function(n, k) {
    let res = [];
    const dfs = (start, temp) => {
        if(temp.length === k) {
            res.push(temp.slice());
            return;
        }
        for(let i = start; i <= n; i++) {
            temp.push(i);
            console.info(temp);
            dfs(i + 1, temp);
            temp.pop();
        }
    }
    // Note that here 1 is the value itself, not the subscript
    dfs(1, []);
    return res;
};

78. Subset No duplicate numbers

Give you an integer array nums. The elements in the array are different from each other. Returns all possible subsets (power sets) of the array.

The solution set cannot contain duplicate subsets. You can return the solution set in any order.

Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
[]Not printed,[]Will join at the beginning res Result set

[ 1 ] 
[ 1, 2 ] 
[ 1, 2, 3 ] 
[ 1, 3 ] 
[ 2 ] 
[ 2, 3 ] 
[ 3 ]
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var subsets = function(nums) {
    let res=[];
    const dfs = (start, temp) => {
        res.push(temp.slice());
        for(let i = start; i < nums.length; i++){
            temp.push(nums[i]);
            console.info(temp);
            dfs(i+1, temp);
            temp.pop();
        }
    };
    // Here 0 is the subscript; [] is also a subset. res will be added at the beginning
    dfs(0,[]);
    return res;
};

90. Subset II Contains duplicate numbers

Give you an integer array nums, which may contain duplicate elements. Please return all possible subsets (power sets) of the array.

The solution set cannot contain duplicate subsets. Subsets of the returned solution set can be arranged in any order.

Input: nums = [1,2,2]
Output: [[],[1],[1,2],[1,2,2],[2],[2,2]]
Do not remove horizontal (same layer) duplicate print results
[ 1 ] [ 1, 2 ] [ 1, 2, 2 ] [ 1, 2 ] [ 2 ] [ 2, 2 ] [ 2 ]
Remove horizontal (same layer) repeated print results; Vertical repeatable
[ 1 ] [ 1, 2 ] [ 1, 2, 2 ] [ 2 ] [ 2, 2 ]
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var subsetsWithDup = function(nums) {
    let res=[];
    nums.sort((a,b)=>a-b);
    const dfs = (start,temp) => {
        res.push(temp.slice());
        for(let i = start; i < nums.length; i++){
            // Remove the horizontal same layer repetition. I > start is better understood, and for is horizontal
            if(i > start && nums[i-1]===nums[i]) continue;
            // if(i-1 >= start && nums[i-1]===nums[i]) continue;
            temp.push(nums[i]);
            dfs(i+1,temp);
            temp.pop();
        }
    }
    dfs(0,[]);
    return res;
};

131. Split palindrome string

Input: s = "aab"
Output: [["a","a","b"],["aa","b"]]
/**
 * @param {string} s
 * @return {string[][]}
 */
var partition = function(s) {
    const isTrue = (str) => {
        return str === str.split('').reverse().join('');
    }
    let res = [];
    const dfs = (start, temp) => {
        if(start === s.length){
            res.push(temp.slice());
            return;
        }
        for(let i = start; i < s.length; i++) {
            if(isTrue(s.substring(start, i + 1))) {
                temp.push(s.substring(start, i + 1));
                dfs(i+1, temp);
                temp.pop();
            }
        }
    }
    dfs(0, []);
    return res;
};

13, leetcode - dynamic programming

509. Fibonacci number

Fibonacci numbers are usually represented by F(n), and the sequence formed is called Fibonacci sequence. The sequence starts with 0 and 1, and each subsequent number is the sum of the first two numbers. That is:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),among n > 1

Here you are n, please calculate F(n).

Input: 4
 Output: 3
 Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3
dp initialization
[ 0, 1 ]
dp Print
[ 0, 1, 1 ] 
[ 0, 1, 1, 2 ] 
[ 0, 1, 1, 2, 3 ]
/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
    let dp = [0, 1];
    for(let i = 2; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
        console.info(dp);
    }
    return dp[n];
};

70. Climb stairs

Suppose you are climbing stairs. You need n steps to reach the roof.

You can climb one or two steps at a time. How many different ways can you climb to the roof?

Note: given n is a positive integer.

Input: 2
 Output: 2
 Explanation: there are two ways to climb to the roof.
1.  1 rank + 1 rank
2.  2 rank
dp[i]: Indicates arrival i Number of steps
dp[i]The value of comes from only these two types: dp[i] = dp[i-1] + dp[i-2];
    ①Arrive from the last step
    ②Reach from the last two steps
Input: 5
 Output: 8
initialization
[ null, 1, 2 ] 
dp Print
[ null, 1, 2, 3 ] 
[ null, 1, 2, 3, 5 ] 
[ null, 1, 2, 3, 5, 8 ]
/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function(n) {
    let dp = [null, 1, 2];
    for(let i = 3; i <= n; i++) {
        dp[i] = dp[i-1] + dp[i-2];
        console.info(dp);
    }
    return dp[n];
};

746. Use the minimum cost to climb stairs

Each subscript of the array is used as a ladder, and the ith ladder corresponds to a non negative physical cost value cost[i] (the subscript starts from 0).

Every time you climb a ladder, you have to spend the corresponding physical strength. Once you pay the corresponding physical strength, you can choose to climb one ladder or two ladders.

Please find out the lowest cost to reach the top of the floor. At the beginning, you can select the element with subscript 0 or 1 as the initial ladder.

Input: cost = [10, 15, 20]
Output: 15
 Explanation: the minimum cost is from cost[1] Start, and then take two steps to the top of the ladder. It costs a total of 15.
Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
Output: 6
 Explanation: the lowest cost is from cost[0] Start, go through those ones one by one, skip cost[3] ,The total cost is 6.
dp[i]: Indicates the arrival of the second i The minimum physical strength spent on each step is dp[i]
initialization
[ 1, 100 ]
dp Print
[ 1, 100, 2 ] 
[ 1, 100, 2, 3 ] 
[ 1, 100, 2, 3, 3 ] 
[ 1, 100, 2, 3, 3, 103 ] 
[ 1, 100, 2, 3, 3, 103, 4 ] 
[ 1, 100, 2, 3, 3, 103, 4, 5 ] 
[ 1, 100, 2, 3, 3, 103, 4, 5, 104 ] 
[ 1, 100, 2, 3, 3, 103, 4, 5, 104, 6 ]
/**
 * @param {number[]} cost
 * @return {number}
 */
var minCostClimbingStairs = function(cost) {
    const dp = [ cost[0], cost[1] ];
    for (let i = 2; i < cost.length; i++) {
        dp[i] = Math.min(dp[i -1] + cost[i], dp[i - 2] + cost[i]);
        console.info(dp);
    }
    return Math.min(dp[cost.length - 1], dp[cost.length - 2]);
};

62. Different paths

A robot is located in the upper left corner of an m x n grid (the starting point is marked "Start" in the following figure).

The robot can only move down or right one step at a time. The robot attempts to reach the lower right corner of the grid (marked "Finish" in the following image).

How many different paths are there altogether?

Input: m = 3, n = 2
 Output: 3
 Explanation:
Starting from the upper left corner, there are a total of 3 paths to the lower right corner.
1. towards the right -> down -> down
2. down -> down -> towards the right
3. down -> towards the right -> down
initialization
[ 
  [ 1, 1 ], 
  [ 1, 0 ], 
  [ 1, 0 ] 
] `
dp Print
[ 
  [ 1, 1 ], 
  [ 1, 2 ], 
  [ 1, 0 ] 
] 
[ 
  [ 1, 1 ], 
  [ 1, 2 ], 
  [ 1, 3 ] 
]
dp[i][j]: Indicates arrival i,j Path at location
dp[i][j]The value of comes from only two directions: dp[i][j] = dp[i-1][j] + dp[i][j-1];
    ①from i,j Reach above position
    ②from i,j Position left arrival
/**
 * @param {number} m
 * @param {number} n
 * @return {number}
 */
var uniquePaths = function(m, n) {
    let dp = new Array(m).fill().map(()=>new Array(n).fill(0));
    for(let i = 0; i < m; i++) dp[i][0] = 1;
    for(let i = 0; i < n; i++) dp[0][i] = 1;
    console.info(dp);
    for(let i = 1; i < m; i++) {
        for(let j = 1; j < n; j++) {
            dp[i][j] = dp[i-1][j] + dp[i][j-1];
            console.info(dp);
        }
    }
    return dp[m-1][n-1];
};

63. Different paths II

A robot is located in the upper left corner of an m x n grid (the starting point is marked "Start" in the following figure).

The robot can only move down or right one step at a time. The robot attempts to reach the lower right corner of the grid (marked "Finish" in the following image).

Now consider that there are obstacles in the mesh. How many different paths will there be from the upper left corner to the lower right corner?

The obstacles and empty positions in the grid are represented by 1 and 0 respectively.
The obstacles and empty positions in the grid are represented by 1 and 0 respectively.

Input: obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
Output: 2
 Explanation:
3x3 There is an obstacle in the middle of the grid.
There are two different paths from the upper left corner to the lower right corner:
1. towards the right -> towards the right -> down -> down
2. down -> down -> towards the right -> towards the right
initialization:
[ 
  [ 1, 1, 1 ], 
  [ 1, 0, 0 ], 
  [ 1, 0, 0 ] 
] 
dp Print
[ 
  [ 1, 1, 1 ], 
  [ 1, 0, 0 ], 
  [ 1, 0, 0 ] 
] 
[ 
  [ 1, 1, 1 ], 
  [ 1, 0, 1 ], 
  [ 1, 0, 0 ] 
] 
[ 
  [ 1, 1, 1 ], 
  [ 1, 0, 1 ], 
  [ 1, 1, 0 ] 
] 
[ 
  [ 1, 1, 1 ], 
  [ 1, 0, 1 ], 
  [ 1, 1, 2 ] 
]
/**
 * @param {number[][]} obstacleGrid
 * @return {number}
 */
var uniquePathsWithObstacles = function(obstacleGrid) {
    let m = obstacleGrid.length;
    let n = obstacleGrid[0].length;
    let dp = new Array(m).fill().map(()=>new Array(n).fill(0));
    for(let i = 0; i < m && obstacleGrid[i][0] === 0; i++) dp[i][0] = 1;
    for(let i = 0; i < n && obstacleGrid[0][i] === 0; i++) dp[0][i] = 1;
    console.info(dp);
    for(let i = 1; i < m; i++) {
        for(let j = 1; j < n; j++) {
            dp[i][j] = obstacleGrid[i][j] === 1 ? 0 : dp[i-1][j] + dp[i][j-1];
            console.info(dp);
        }
    }
    return dp[m-1][n-1];
};

118. Yanghui triangle

Given a nonnegative integer numRows, the first numRows of the Yang Hui triangle are generated.

In the Yang Hui triangle, each number is the sum of its upper left and upper right numbers.

input: numRows = 5
 output: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
[ [] ] 
[ [ 1 ] ] 
------- 
[ [ 1 ], [] ] 
[ [ 1 ], [ 1, 1 ] ] 
------- 
[ [ 1 ], [ 1, 1 ], [] ] 
[ [ 1 ], [ 1, 1 ], [ 1, 2, 1 ] ] 
------- 
[ [ 1 ], [ 1, 1 ], [ 1, 2, 1 ], [] ] 
[ [ 1 ], [ 1, 1 ], [ 1, 2, 1 ], [ 1, 3, 3, 1 ] ] 
------- 
[ [ 1 ], [ 1, 1 ], [ 1, 2, 1 ], [ 1, 3, 3, 1 ], [] ] 
[ [ 1 ], [ 1, 1 ], [ 1, 2, 1 ], [ 1, 3, 3, 1 ], [ 1, 4, 6, 4, 1 ] ] 
-------
/**
 * @param {number} numRows
 * @return {number[][]}
 */
var generate = function(numRows) {
    let dp = [];
    for (let i = 0; i < numRows; i++) {
        dp[i] = [];
        console.info(dp);
        for(let j = 0; j <= i; j++){
            if(j ===  0  || j === i) {
                // When it is both sides of Yang Hui triangle, it is directly assigned as 1
                dp[i][j] = 1;
            } else {
                // Otherwise, the current value is the sum of the upper left and upper right values
                dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
            }
        }      
        console.info(dp);
        console.info('-------');
    }
    return dp;
};
dp[i]: Represents a split number i The maximum product that can be obtained is dp[i]

647. Palindrome substring

Give you a string s, please count and return the number of palindrome substrings in this string.

Palindrome strings are the same strings that are being read and read backwards.

A substring is a sequence of consecutive characters in a string.

Substrings with different start or end positions, even if they are composed of the same characters, will be regarded as different substrings.

Input: s = "aaa"
Output: 6
 Explanation: 6 palindrome substrings: "a", "a", "a", "aa", "aa", "aaa"
/**
 * @param {string} s
 * @return {number}
 */
var countSubstrings = function(s) {
    let res = 0;
    let len = s.length;
    // dp[i][j]: indicates whether the substring of interval range [i,j] is a palindrome substring
    // true if dp[i][j], false otherwise. Initialize to false
    let dp = new Array(len).fill().map(() => new Array(len).fill(false));
    // Traverse from bottom to top and from left to right. Ensure that dp[i + 1][j - 1] is calculated
    for (let i = len - 1; i >= 0; i--) {  
        for (let j = i; j < len; j++) {
            if (s[i] == s[j]) {
                // When the string is 1 or 2, such as a or aa, it is a palindrome substring
                // Otherwise, it depends on whether it is also a palindrome substring
                if (j - i <= 1) { 
                    res++;
                    dp[i][j] = true;
                } else if (dp[i + 1][j - 1]) { 
                    res++;
                    dp[i][j] = true;
                }
            }
        }
    }
    return res;
};
dp1 It is an auxiliary code used for printing, and the actual ac The code can be removed
[ 
  [ false, false, false ], 
  [ false, false, false ], 
  [ false, false, true ] 
] 
[ 
  [ false, false, false ], 
  [ false, false, false ], 
  [ false, false, 'a' ] 
] 
=========
[ 
  [ false, false, false ], 
  [ false, true, true ], 
  [ false, false, true ] 
] 
[ 
  [ false, false, false ], 
  [ false, 'a', 'aa' ], 
  [ false, false, 'a' ] 
] 
=========
[ 
  [ true, true, true ], 
  [ false, true, true ], 
  [ false, false, true ] 
] 
[ 
  [ 'a', 'aa', 'aaa' ], 
  [ false, 'a', 'aa' ], 
  [ false, false, 'a' ] 
]
=========
/**
 * @param {string} s
 * @return {number}
 */
var countSubstrings = function(s) {
    let res = 0;
    let len = s.length;
    let dp = new Array(len).fill().map(() => new Array(len).fill(false));
    let dp1 = new Array(len).fill().map(() => new Array(len).fill(false));
    for (let i = len - 1; i >= 0; i--) {  
        for (let j = i; j < len; j++) {
            if (s[i] == s[j] && (j - i <= 1 || dp[i + 1][j - 1])) {
                res++;
                dp[i][j] = true;
            }
            dp1[i][j] = s.substring(i, j + 1);
        }
        console.info(dp);
        console.info(dp1);
        console.info('=========');
    }
    return res;
};

5. Longest palindrome substring

Give you a string s and find the longest palindrome substring in S.

Input: s = "babad"
Output: "bab"
Explanation: "aba" The same answer is in line with the meaning of the question.
dp[i][j]: Represents a substring s[i]reach s[j]Is it a palindrome substring
dp[i][j] = s[i] === s[j] && (j - i < 2 || dp[i + 1][j - 1]); Represents the nature of the palindrome string

44, 33, 34, 22, 23, 24, 11, 12, 13, 14, 00, 01, 02, 03, 04 Traversal in the order of

When traversing to 24, follow dp[i][j] = s[i] === s[j] && (j - i < 2 || dp[i + 1][j - 1]),
4-2<2 || dp[2+1][4-1], 4-2<2 It doesn't meet the requirements, so you need to know dp[3][3],
And 33 there are already results in the previous traversal (for true),So the result of 24 can also be obtained.
dp1 It is an auxiliary code used for printing, and the actual ac The code can be removed
[ 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, false, true ] 
] 
[ 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, false, 'd' ] 
] 
========= 
[ 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, true, false ], 
  [ false, false, false, false, true ] 
] 
[ 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, false, 'a', 'ad' ], 
  [ false, false, false, false, 'd' ] 
] 
========= 
[ 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, true, false, false ], 
  [ false, false, false, true, false ], 
  [ false, false, false, false, true ] 
] 
[ 
  [ false, false, false, false, false ], 
  [ false, false, false, false, false ], 
  [ false, false, 'b', 'ba', 'bad' ], 
  [ false, false, false, 'a', 'ad' ], 
  [ false, false, false, false, 'd' ] 
] 
========= 
[ 
  [ false, false, false, false, false ], 
  [ false, true, false, true, false ], 
  [ false, false, true, false, false ], 
  [ false, false, false, true, false ], 
  [ false, false, false, false, true ] 
] 
[ 
  [ false, false, false, false, false ], 
  [ false, 'a', 'ab', 'aba', 'abad' ], 
  [ false, false, 'b', 'ba', 'bad' ], 
  [ false, false, false, 'a', 'ad' ], 
  [ false, false, false, false, 'd' ] 
] 
========= 
[ 
  [ true, false, true, false, false ], 
  [ false, true, false, true, false ], 
  [ false, false, true, false, false ], 
  [ false, false, false, true, false ], 
  [ false, false, false, false, true ] 
] 
[ 
  [ 'b', 'ba', 'bab', 'baba', 'babad' ], 
  [ false, 'a', 'ab', 'aba', 'abad' ], 
  [ false, false, 'b', 'ba', 'bad' ], 
  [ false, false, false, 'a', 'ad' ], 
  [ false, false, false, false, 'd' ] 
] 
=========
/**
 * @param {string} s
 * @return {string}
 */
var longestPalindrome = function(s) {
    let res = '';
    let len = s.length;
    let dp = new Array(len).fill().map(() => new Array(len).fill(false));
    let dp1 = new Array(len).fill().map(() => new Array(len).fill(false));
    for (let i = len - 1; i >= 0; i--) {
        for (let j = i; j < len; j++) {
            dp[i][j] = s[i] === s[j] && (j - i <= 1 || dp[i + 1][j - 1]);
            // If it is a palindrome string and is greater than the length of the last palindrome string, the result will be updated
            if (dp[i][j] && j - i + 1 > res.length) {
                res = s.substring(i, j + 1);
            }
            dp1[i][j] = s.substring(i, j + 1);
        }
        console.info(dp);
        console.info(dp1);
        console.info('=========');
    }
    return res;
};

516. Longest palindrome subsequence

Give you a string s, find the longest palindrome subsequence, and return the length of the sequence.

Subsequence is defined as a sequence formed by deleting some characters or not deleting any characters without changing the order of the remaining characters.

Input: s = "bbbab"
Output: 4
 Explanation: one possible longest palindrome subsequence is "bbbb" . 
i=4 
[ 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 1 ] ] 
[ 
  [ 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 'b' ] ] 
========= 
i=3 j=4 
[ 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 1, 1 ], 
  [ 0, 0, 0, 0, 1 ] ] 
[ 
  [ 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 'a', 'ab' ], 
  [ 0, 0, 0, 0, 'b' ] ] 
========= 
i=2 j=3 j=4 
[ 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 1, 1, 3 ], 
  [ 0, 0, 0, 1, 1 ], 
  [ 0, 0, 0, 0, 1 ] ] 
[ 
  [ 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 0, 'b', 'ba', 'bab' ], 
  [ 0, 0, 0, 'a', 'ab' ], 
  [ 0, 0, 0, 0, 'b' ] ] 
========= 
i=1 j=2 j=3 j=4 
[ 
  [ 0, 0, 0, 0, 0 ], 
  [ 0, 1, 2, 2, 3 ], 
  [ 0, 0, 1, 1, 3 ], 
  [ 0, 0, 0, 1, 1 ], 
  [ 0, 0, 0, 0, 1 ] ] 
[ 
  [ 0, 0, 0, 0, 0 ],
  [ 0, 'b', 'bb', 'bba', 'bbab' ], 
  [ 0, 0, 'b', 'ba', 'bab' ], 
  [ 0, 0, 0, 'a', 'ab' ], 
  [ 0, 0, 0, 0, 'b' ] ] 
========= 
i=0 j=1 j=2 j=3 j=4 
[ 
  [ 1, 2, 3, 3, 4 ], 
  [ 0, 1, 2, 2, 3 ], 
  [ 0, 0, 1, 1, 3 ], 
  [ 0, 0, 0, 1, 1 ], 
  [ 0, 0, 0, 0, 1 ] ] 
[ 
  [ 'b', 'bb', 'bbb', 'bbba', 'bbbab' ], 
  [ 0, 'b', 'bb', 'bba', 'bbab' ], 
  [ 0, 0, 'b', 'ba', 'bab' ], 
  [ 0, 0, 0, 'a', 'ab' ], 
  [ 0, 0, 0, 0, 'b' ] ] 
=========
/**
 * @param {string} s
 * @return {number}
 */
var longestPalindromeSubseq = function(s) {
    let len = s.length;
    let dp = Array.from(new Array(len)).map(() => new Array(len).fill(0));
    let dp1 = Array.from(new Array(len)).map(() => new Array(len).fill(0));
    // i traverses from bottom to top and j traverses from left to right
    for (let i = len - 1; i >= 0; i--) {
        dp[i][i] = 1; // A single character must be a palindrome string
        dp1[i][i] = s.substring(i, i + 1);
        console.info('i='+i);
        for (let j = i + 1; j < len; j++) {
            console.info('j='+j);
            if (s[i] === s[j]) {
                // Description in subsequence, + 2
                dp[i][j] = dp[i + 1][j - 1] + 2;
            } else {
                // dp[i][j] indicates that the length of the longest palindrome subsequence of string s in the range of [i, j] is dp[i][j]
                dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
            }
            dp1[i][j] = s.substring(i, j + 1);
        }
        console.info(dp);
        console.info(dp1);
        console.info('=========');
    }
    return dp[0][len-1];
};

53. Maximum subsequence sum

Given an integer array nums, find a continuous sub array with the largest sum (the sub array contains at least one element) and return its maximum sum.

Example 1:
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
 Explanation: continuous subarray [4,-1,2,1] The sum of is 6.
dp[i]: Indicates including subscripts i Previous maximum continuous subsequence sum
dp[i]The value of comes from the larger of two cases: dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
    ①yes i When the previous maximum sub order sum is positive, i The maximum suborder sum of is dp[i-1] + Current value nums[i]
    ②yes i When the previous maximum sub order sum is negative, i The maximum sub order sum of is the current value nums[i]
    
Calculate each subscript i And continuously update the largest one.
[ -2 ] 
[ -2, 1 ] 
[ -2, 1, -2 ] 
[ -2, 1, -2, 4 ] 
[ -2, 1, -2, 4, 3 ] 
[ -2, 1, -2, 4, 3, 5 ] 
[ -2, 1, -2, 4, 3, 5, 6 ] 
[ -2, 1, -2, 4, 3, 5, 6, 1 ] 
[ -2, 1, -2, 4, 3, 5, 6, 1, 5 ]
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    let res = nums[0];
    let dp = [nums[0]];
    console.info(dp);
    for(let i = 1; i < nums.length; i++) {
        dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
        console.info(dp);
        res = Math.max(res, dp[i]);
    }
    return res;
};
iteration nums array
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    let res = nums[0];
    let sum = 0;
    for(let num of nums) {
        if(sum > 0) {
            sum += num;
        } else {
            sum = num;
        }
        res = Math.max(res, sum);
    }
    return res;
};

198. House raiding

You are a professional thief who plans to steal houses along the street. There is a certain amount of cash hidden in each room. The only restrictive factor affecting your theft is that the adjacent houses are equipped with interconnected anti-theft systems. If two adjacent houses are intruded by thieves on the same night, the system will automatically alarm.

Given a non negative integer array representing the amount stored in each house, calculate the maximum amount you can steal overnight without touching the alarm device.

Input:[1,2,3,1]
Output: 4
 Explanation: stealing house 1 (amount of money = 1) ,Then steal house 3 (amount of money = 3). 
     Maximum amount stolen = 1 + 3 = 4 . 
dp[i]: It means stealing to the third party i The maximum amount you can steal from a house
dp[i]The value of comes from the larger of two cases: dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
    Because you have to steal from another house, so
    ①When i If it is a house that cannot be stolen, the amount of theft is the amount when the previous house is stolen, i.e dp[i-1]
    ②yes i When it is a house that can be stolen, the amount of theft is the amount of theft to the last house+Amount stolen to current house
     Namely dp[i-2] + nums[i]
[ 1, 2 ] 
[ 1, 2, 4 ] 
[ 1, 2, 4, 4 ]
/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
    let len = nums.length;
    let dp = [nums[0], Math.max(nums[0], nums[1])];
    console.info(dp);
    for(let i = 2; i < len; i++){
        dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
        console.info(dp);
    }
    return dp[len-1];
};

213. House raiding II

You are a professional thief. You plan to steal houses along the street. There is a certain amount of cash in each room. All the houses in this place are in a circle, which means that the first house and the last house are next to each other. At the same time, adjacent houses are equipped with interconnected anti-theft systems. If two adjacent houses are intruded by thieves on the same night, the system will automatically alarm.

Given a non negative integer array representing the amount stored in each house, calculate the maximum amount you can steal tonight without touching the alarm device.

Input: nums = [2,3,2]
Output: 3
 Explanation: 
    You can't steal house 1 first = 2),Then steal house 3 (amount) = 2), 
    Because they are adjacent.
/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
    let len = nums.length;
    if(len === 0) return 0;
    if(len === 1) return nums[0];
    let res1 = 0; let res2 = 0;
    let dp = [];
    // Don't steal the first one, start from room 0 and 2
    dp = [0, nums[1]];
    for(let i = 2; i <= len - 1; i++) {
        dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
    }
    res1 = dp[len - 1];
    // Don't steal the last one, start from room 1 and 3
    dp = [nums[0], Math.max(nums[0], nums[1])];
    for(let i = 2; i <= len - 2; i++) {
        dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
    }
    res2 = dp[len - 2];
    return Math.max(res1, res2);
};

337. House raiding III

After robbing a street and a circle of houses last time, the thief found a new area that could be stolen. This area has only one entrance, which we call "root". In addition to "root", each house has and only one "father" house connected to it. After some reconnaissance, the smart thief realized that "The arrangement of all houses in this place is similar to a binary tree". If two directly connected houses are robbed on the same night, the house will automatically call the police.

Calculate the maximum amount a thief can steal a night without triggering the alarm.

input: [3,2,3,null,3,null,1]

     3
    / \
   2   3
    \   \ 
     3   1

output: 7 
explain: The maximum amount a thief can steal in a night = 3 + 3 + 1 = 7.
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var rob = function(root) {
    let dfs = (node) => {
        if (!node) return [0, 0];
        let l = dfs(node.left);
        let r = dfs(node.right);
        // The current node is stolen, and the child node cannot be stolen
        let select = node.val + l[1] + r[1];
        // The current node is not stolen, and the child node can be stolen or not
        let notSelect = Math.max(l[0], l[1]) + Math.max(r[0], r[1]);
        return [select, notSelect];
    }
    let res = dfs(root);
    return Math.max(...res);
};

322. Change

Give you an integer array of coins, which represents coins of different denominations; and an integer amount, which represents the total amount.

Calculate and return the minimum number of coins required to make up the total amount. If no combination of coins can make up the total amount, return - 1.

You can think that the number of each coin is unlimited.

Input: coins = [1, 2, 5], amount = 11
 Output: 3 
Interpretation: 11 = 5 + 5 + 1
dp[i]: Means to get together i The minimum number of coins required for the amount 
dp[i]The value of comes from the smaller of two cases: dp[i] = Math.min(dp[i], dp[i-coin] + 1);
    ①Does not include the current number of coins
    ②Contains the current coins, i.e. the current number of coins is 1 + Deduct current coin amount coin Number of coins after dp[i-coin];
initialization
[0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11]
dp Print
[0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11]
[0, 1, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11]
[0, 1, 1, 11, 11, 11, 11, 11, 11, 11, 11, 11]
[0, 1, 1, 2, 11, 11, 11, 11, 11, 11, 11, 11]
[0, 1, 1, 2, 2, 11, 11, 11, 11, 11, 11, 11]
[0, 1, 1, 2, 2, 1, 11, 11, 11, 11, 11, 11]
[0, 1, 1, 2, 2, 1, 2, 11, 11, 11, 11, 11]
[0, 1, 1, 2, 2, 1, 2, 2, 11, 11, 11, 11]
[0, 1, 1, 2, 2, 1, 2, 2, 3, 11, 11, 11]
[0, 1, 1, 2, 2, 1, 2, 2, 3, 3, 11, 11]
[0, 1, 1, 2, 2, 1, 2, 2, 3, 3, 2, 11]
[0, 1, 1, 2, 2, 1, 2, 2, 3, 3, 2, 3];
/**
 * @param {number[]} coins
 * @param {number} amount
 * @return {number}
 */
var coinChange = function(coins, amount) {
    let dp = new Array(amount + 1).fill(Infinity);
    dp[0] = 0;
    for(let i = 0; i <= amount; i++) {
        for(let coin of coins) {
            if(i-coin >= 0) {
                dp[i] = Math.min(dp[i], dp[i-coin] + 1);
            }
        }
    }
    return dp[amount] === Infinity ? -1 : dp[amount];
};

121. The best time to buy and sell stocks

Trading once, no interval, no handling charge

Given an array of prices, its ith element prices[i] represents the price of a given stock on day I.

You can only choose to buy this stock one day and sell it on a different day in the future. Design an algorithm to calculate the maximum profit you can make.

Returns the maximum profit you can make from this transaction. If you can't make any profit, return 0.

Input:[7,1,5,3,6,4]
Output: 5
 Explanation:
    On day 2 (stock price) = 1)When you buy,
    On day 5 (stock price) = 6)When you sell, you make the most profit = 6-1 = 5 . 
    Note that the profit cannot be 7-1 = 6, Because the selling price needs to be greater than the buying price;
    At the same time, you can't sell stocks before buying.
/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {
    let profits = 0; // Maximum profit, initialized to 0
    let min = prices[0]; // Minimum price, initialized to the price of the current first day
    for (let i = 0; i < prices.length; i++) {
        // Keep the minimum price
        min = Math.min(min, prices[i]);
        // Continuously update the maximum profit
        profits = Math.max(profits, prices[i] - min);
    }
    return profits;
};

122. The best time to buy and sell stocks II

Multiple transactions, no interval, no handling fee

Give an array prices, where prices[i] is the price of a given stock on day I.

Design an algorithm to calculate the maximum profit you can make. You can complete as many transactions as possible (buying and selling a stock multiple times).

Note: you cannot participate in multiple transactions at the same time (you must sell the previous shares before buying again).

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {
    let profits = 0; // The maximum profit is initialized to 0
    for (let i = 0; i < prices.length; i++) {
        // Add when there is profit, which is equivalent to selling on the same day and buying on the same day
        if(prices[i + 1] > prices[i]) {
            profits += prices[i + 1] - prices[i]
        }
    }
    return profits;
};

14, leetcode - greedy

55. Jumping game

Given a nonnegative integer array nums, you are initially at the first subscript of the array.

Each element in the array represents the maximum length you can jump at that position.

Judge whether you can reach the last subscript.

Input: nums = [2,3,1,1,4]
Output: true
 Explanation: you can skip step 1 to reach subscript 1 from subscript 0, Then jump 3 steps from subscript 1 to the last subscript.
/**
 * @param {number[]} nums
 * @return {boolean}
 */
var canJump = function(nums) {
    let cover = 0;
    // Cycle the number of steps that can be taken to continuously update the maximum coverage
    for(let i = 0; i <= cover; i++) {
        cover = Math.max(cover, i + nums[i]);
        if(cover >= nums.length - 1) return true;
    }
    return false;
};

134. Gas stations

There are N gas stations on a ring road, of which the ith gas station has gasoline gas[i] liters.

You have a car with unlimited fuel tank capacity. It takes cost[i] liters of gasoline to drive from the ith gas station to the I + 1st gas station. You start from one of the gas stations and start with an empty tank.

If you can drive around the loop, return to the number of the gas station at the time of departure, otherwise return to - 1.

explain:

If the question has a solution, the answer is the only answer.
The input arrays are all non empty arrays with the same length.
All elements in the input array are non negative numbers.

input: 
gas  = [1,2,3,4,5]
cost = [3,4,5,1,2]

output: 3

explain:
From gas station 3(3 indexes)Starting, you can get 4 liters of gasoline. At this time, there is oil in the oil tank = 0 + 4 = 4 Litres of gasoline
 Drive to No. 4 gas station. There are 4 in the fuel tank at this time - 1 + 5 = 8 Litres of gasoline
 Drive to No. 0 gas station. There are 8 in the fuel tank at this time - 2 + 1 = 7 Litres of gasoline
 Drive to No. 1 gas station, and there are 7 in the fuel tank - 3 + 2 = 6 Litres of gasoline
 Drive to No. 2 gas station. There are 6 tanks at this time - 4 + 3 = 5 Litres of gasoline
 You need to consume 5 liters of gasoline to drive to gas station 3, which is just enough for you to return to gas station 3.
Therefore, 3 can be the starting index.
/**
 * @param {number[]} gas
 * @param {number[]} cost
 * @return {number}
 */
var canCompleteCircuit = function(gas, cost) {
    const gasLen = gas.length;
    let start = 0;
    let left = 0;
    let totalSum = 0;
    for(let i = 0; i < gasLen; i++) {
        let curLeft = gas[i] - cost[i];
        left += curLeft;
        totalSum += curLeft;
        if(left < 0) {
            left = 0;
            start = i + 1;
        }
    }
    return totalSum < 0 ? -1 : start;
};

455. Distribution of biscuits

Suppose you are a great parent and want to give your children some cookies. However, each child can only give one biscuit at most.

For each child I, there is an appetite value g[i], which is the minimum size of biscuits that can satisfy the children's appetite; And every cookie j has a size s[j]. If s[j] > = g[i], we can assign this biscuit j to child I, and the child will be satisfied. Your goal is to meet as many children as possible and output this maximum value.

input: g = [1,2], s = [1,2,3]
output: 2
 explain: 
You have two children and three cookies. The appetite values of two children are 1,2. 
You have enough cookies and sizes to satisfy all children.
So you should output 2.
/**
 * @param {number[]} g
 * @param {number[]} s
 * @return {number}
 */
var findContentChildren = function(g, s) {
    g.sort((a, b) => a - b);
    s.sort((a, b) => a - b);
    let res = 0;
    let index = s.length - 1;
    for(let i = g.length - 1; i >= 0; i--) {
        // Big biscuits first satisfy children with big appetites
        if(index >= 0 && s[index] >= g[i]) {
            res++;
            index--;
        }
    } 
    return res;
};

Tags: Javascript Algorithm leetcode Visual Studio Code

Posted on Mon, 22 Nov 2021 19:57:06 -0500 by ShashidharNP