LEETCODE (11-20) OF JS ALGORITHM PROBLEMS

Keywords: Javascript REST


Ten topics are easier this time. Let's go through them briefly.
Sources of the following topics leetcode

Containers for the maximum amount of water

Topic Description

Given n n n nonnegative integers a1, a2,..., an, each number represents a point (i, ai) in the coordinates. Draw n vertical lines in coordinates. The two endpoints of vertical line I are (i, ai) and (i, 0). Find out two of these lines so that the containers consisting of them and the x-axis can hold as much water as possible.

Note: You can't tilt the container, and the value of n is at least 2.

The vertical line in the figure represents the input array [1, 8, 6, 2, 5, 4, 8, 3, 7]. In this case, the maximum capacity of the container to hold water (represented as the blue part) is 49.

Example

Input: [1, 8, 6, 2, 5, 4, 8, 3, 7]
Output: 49

Answer

As a medium-difficulty topic, it is relatively easy, and the level is not deep. We go through two levels directly, and we can get better results by comparing them.

var maxFunc = (a, b) => {
    return a >= b ? a : b;
}

var minFunc = (a, b) => {
    return a <= b ? a : b;
}

var maxArea = function(height) {
    let max = 0;

    for(let i = 0; i < height.length - 1; i++){
        for(let j = i + 1; j < height.length ; j++){
            let temp = (j - i) * minFunc(height[i], height[j]);
            max = maxFunc(max, temp);
        }
    }

    return max;
};

Integer to Roman numerals

Topic Description

Roman numerals contain the following seven characters: I, V, X, L, C, D and M.

character          numerical value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, the Roman numeral 2 is written as II, which is one of two juxtapositions. 12 is written as XII, which is X + II. Write XXVII, that is XX + V + II.

Normally, small numbers in Roman numerals are on the right side of large numbers. But there are also exceptions, such as IV instead of IIII. The number 1 is on the left side of the number 5, and the number represented is equal to the value 4 obtained by the large number 5 and the reduced number 1. Similarly, the number 9 is represented as IX. This special rule applies only to the following six cases:

I can be placed on the left of V (5) and X (10) to represent 4 and 9.
X can be placed on the left of L (50) and C (100) to represent 40 and 90.  
C can be placed on the left of D (500) and M (1000) to represent 400 and 900.

Given an integer, convert it to a Roman number. Entry is guaranteed in the range of 1 to 3999.

Example

Input: 3
 Output: "III"
Input: 4
 Output: "IV"
Input: 9
 Output: "IX"
Input: 58
 Output: "LVIII"
Interpretation: L = 50, V = 5, III = 3.
Input: 1994
 Output: "MCMXCIV"
Interpretation: M = 1000, CM = 900, XC = 90, IV = 4.

Answer

It's not difficult. We just need to deal with the Roman numerals one by one, take the remainder and take the model, and then judge.

var intToRoman = function(num) {
    let divisor = 0, remainder = 0, str = '';
    // M,1000
    divisor = Math.floor(num / 1000);
    remainder = num % 1000;
    while(divisor){
        str += 'M';
        divisor--;
    }
    if(remainder >= 900){
        str += 'CM';
        remainder -= 900;
    }
    // D,500
    divisor = Math.floor(remainder / 500);
    remainder = remainder % 500;
    while(divisor){
        str += 'D';
        divisor--;
    }
    if(remainder >= 400){
        str += 'CD';
        remainder -= 400;
    }
    // C,100
    divisor = Math.floor(remainder / 100);
    remainder = remainder % 100;
    while(divisor){
        str += 'C';
        divisor--;
    }
    if(remainder >= 90){
        str += 'XC';
        remainder -= 90;
    }
    // L,50
    divisor = Math.floor(remainder / 50);
    remainder = remainder % 50;
    while(divisor){
        str += 'L';
        divisor--;
    }
    if(remainder >= 40){
        str += 'XL';
        remainder -= 40;
    }
    // X,10
    divisor = Math.floor(remainder / 10);
    remainder = remainder % 10;
    while(divisor){
        str += 'X';
        divisor--;
    }
    if(remainder >= 9){
        str += 'IX';
        remainder -= 9;
    }
    // V,5
    divisor = Math.floor(remainder / 5);
    remainder = remainder % 5;
    while(divisor){
        str += 'V';
        divisor--;
    }
    if(remainder >= 4){
        str += 'IV';
        remainder -= 4;
    }
    // I,1
    divisor = remainder;
    while(divisor){
        str += 'I';
        divisor--;
    }

    return str;
};

Roman numeral to integer

Topic Description

Roman numerals contain the following seven characters: I, V, X, L, C, D and M.

character          numerical value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, the Roman numeral 2 is written as II, which is one of two juxtapositions. 12 is written as XII, which is X + II. Write XXVII, that is XX + V + II.

Normally, small numbers in Roman numerals are on the right side of large numbers. But there are also exceptions, such as IV instead of IIII. The number 1 is on the left side of the number 5, and the number represented is equal to the value 4 obtained by the large number 5 and the reduced number 1. Similarly, the number 9 is represented as IX. This special rule applies only to the following six cases:

I can be placed on the left of V (5) and X (10) to represent 4 and 9.
X can be placed on the left of L (50) and C (100) to represent 40 and 90.  
C can be placed on the left of D (500) and M (1000) to represent 400 and 900.

Given a Roman number, convert it into an integer. Entry is guaranteed in the range of 1 to 3999.

Example

Input: "III"
Output: 3
Input: "IV"
Output: 4
Input: "IX"
Output: 9
Input: "LVIII"
Output: 58
 Interpretation: L = 50, V= 5, III = 3.
Input: "MCMXCIV"
Output: 1994
 Interpretation: M = 1000, CM = 900, XC = 90, IV = 4.

Answer

This problem is not difficult. If the first two characters match 4, 9, 40, 90, 400, 900, the two will be processed together, otherwise, one will be processed, and the rest will continue to recurse.

var romanToInt = function(s) {
    if(s.length == 0){
        return 0;
    }
    else if(s.lenght == 1){
        switch(s){
            case "I":
                return 1;
            case "V":
                return 5;
            case "X":
                return 10;
            case "L":
                return 50;
            case "C":
                return 100;
            case "D":
                return 500;
            case "M":
                return 1000;
        }
    }
    else{
        let str = s.substring(0, 2);
        if(str == "IV" || str == "IX" || str == "XL" || str == "XC" || str == "CD" || str == "CM"){
            switch(str){
                case "IV":
                    return 4 + romanToInt(s.slice(2));
                case "IX":
                    return 9 + romanToInt(s.slice(2));
                case "XL":
                    return 40 + romanToInt(s.slice(2));
                case "XC":
                    return 90 + romanToInt(s.slice(2));
                case "CD":
                    return 400 + romanToInt(s.slice(2));
                case "CM":
                    return 900 + romanToInt(s.slice(2));
            }
        }
        else{
            switch(s[0]){
                case "I":
                    return 1 + romanToInt(s.slice(1));
                case "V":
                    return 5 + romanToInt(s.slice(1));
                case "X":
                    return 10 + romanToInt(s.slice(1));
                case "L":
                    return 50 + romanToInt(s.slice(1));
                case "C":
                    return 100 + romanToInt(s.slice(1));
                case "D":
                    return 500 + romanToInt(s.slice(1));
                case "M":
                    return 1000 + romanToInt(s.slice(1));
            }
        }
    }
};

Longest Common Prefix

Topic Description

Write a function to find the longest common prefix in a string array.
If there is no common prefix, return the empty string ".
Explain:
All inputs contain only the lowercase letter a-z.

Example

Input: ["flower","flow","flight"]
Output: "fl"
Input: ["dog","racecar","car"]
Output: ""
Interpretation: There is no public prefix for input.

Answer

This is not a difficult problem. We traverse every character of the string of the array directly, adding the same prefix, or returning it.

var longestCommonPrefix = function(strs) {
    if(strs.length == 0){
        return "";
    }
    if(strs.length == 1){
        return strs[0];
    }

    let minLen = -1, prefix = '', char = '';
    strs.forEach(ele => {
        if(minLen == -1){
            minLen = ele.length;
        }
        else{
            minLen = ele.length < minLen ? ele.length : minLen;
        }
    });
    if(minLen == 0){
        return "";
    }

    for(let i = 0; i < minLen; i++){
        char = strs[0][i];
        // Used to mark whether the character is a prefix
        let flag = true;
        for(let j = 1; j < strs.length; j++){
            if(strs[j][i] != char){
                flag = false;
            }
        }
        if(flag){
            prefix += char;
        }
        else{
            return prefix;
        }
    }
    return prefix;
};

The sum of three numbers

Topic Description

Given a n array of N integers nums, determine whether there are three elements a, b, c in nums, such that a + b + c = 0? Find out all triples that satisfy the conditions and do not repeat.

Note: The answer should not contain duplicate triples.

For example, given array nums = [-1, 0, 1, 2, -1, -4],

The set of triples satisfying the requirements is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

Answer

We use the idea of sorting + double pointers to solve this problem. After traversing the sorted array, we define pointers l and r, and then move from the next element of the current traversing element and the last element of the array to the middle, respectively. The calculated results are compared with the target.

var threeSum = function(nums) {
    if(nums.length < 3){
        return [];
    }

    let res = [];
    // sort
    nums.sort((a, b) => a - b);
    for(let i = 0; i < nums.length; i++){
        if(i > 0 && nums[i] == nums[i-1]){
            // Duplicate removal
            continue;
        }
        if(nums[i] > 0){
            // If the current element is greater than 0, then the sum of the three elements must be greater than 0.
            break;
        }
        // l is left subscript and r is right subscript
        let l = i + 1; r = nums.length - 1;
        while(l<r){
            let sum = nums[i] + nums[l] + nums[r];
            if(sum == 0){
                res.push([nums[i], nums[l], nums[r]]);
                while(l < r && nums[l] == nums[l+1]){
                    l++
                }
                while(l < r && nums[r] == nums[r-1]){
                    r--;
                }
                l++;
                r--;
            }
            else if(sum < 0){
                l++;
            }
            else if(sum > 0){
                r--;
            }
        }
    }

    return res;
};

The closest sum of three numbers

Topic Description

Given an array of n integers, nums, and a target value. Find out three integers in nums so that they are closest to target. Returns the sum of these three numbers. Assume that only one answer exists for each set of inputs.

For example, given array nums = [-1, 2, 1, - 4], and target = 1.

The sum of the three closest numbers to target is 2. (-1 + 2 + 1 = 2).

Answer

This is the same idea as the one above. It's also sort + double pointer, but we need to maintain an additional difference to compare to get the minimum difference.

var threeSumClosest = function(nums, target) {
    if(nums.length == 0){
        return 0;
    }
    else if(nums.length < 4){
        return nums.reduce((a, b) => a + b)
    }
    else {
        let min = -1, res;
        nums.sort((a, b) => a - b);
        for(let i = 0; i < nums.length - 2; i++){
            if(i > 0 && nums[i] == nums[i - 1]){
                // Duplicate removal
                continue;
            }
            let l = i + 1, r = nums.length - 1;
            while(l < r){
                let sum = nums[i] + nums[l] + nums[r];
                if(sum == target){
                    // Gap 0, direct result
                    return sum;
                }
                else if(sum > target){
                    if(min == -1){
                        min = sum - target;
                        res = sum;
                    }
                    else if(sum - target < min){
                        min = sum - target;
                        res = sum;
                    }
                    r--;
                }
                else if(sum < target){
                    if(min == -1){
                        min = target - sum;
                        res = sum;
                    }
                    else if(target - sum< min){
                        min = target - sum;
                        res = sum;
                    }
                    l++;
                }
            }
        }
        return res;
    }
};

Letter Combination of Telephone Numbers

Topic Description

Given a string containing only the numbers 2-9, return all the combinations of letters that it can represent.
The mapping of numbers to letters is given as follows (the same as the telephone button). Note that 1 does not correspond to any letter.

Example

Input: "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

Answer

It's a simple problem, traverse the characters directly, and then add the arrays together. Don't worry about the high complexity, because the cardinality is 3 or 4.

const numMap = {
    2: ['a', 'b', 'c'],
    3: ['d', 'e', 'f'],
    4: ['g', 'h', 'i'],
    5: ['j', 'k', 'l'],
    6: ['m', 'n', 'o'],
    7: ['p', 'q', 'r', 's'],
    8: ['t', 'u', 'v'],
    9: ['w', 'x', 'y', 'z']
}

var letterCombinations = function(digits) {
    if(digits.length == 0){
        return []
    }
    let res = [...numMap[digits[0]]];
    for(let i = 1; i < digits.length; i++){
        let temp = [];
        for(let j = 0; j < res.length; j++){
            for(let k = 0; k < numMap[digits[i]].length; k++){
                temp.push(res[j]+numMap[digits[i]][k]);
            }
        }
        res = [...temp]
    }
    return res;
};

Sum of Four Numbers

Topic Description

Given a n array of N integers nums a n d a target value, judge whether there are four elements a, b, c and D in nums, so that the value of a + b + c + d is equal to that of target? Find out all quaternions that satisfy the conditions and do not repeat.

Be careful:
The answer should not contain duplicate quaternions.

Example

Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.

The set of quaternions satisfying the requirements is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]

Answer

This question is similar to the sum of three numbers. It's the same idea, but this time it's a two-level cycle plus two pointers.
var fourSum = function(nums, target) {

if(nums.length < 4){
    return [];
}
let res = [];
nums.sort((a, b) => a - b);
for(let i = 0; i < nums.length - 3; i++){
    if(i > 0 && nums[i] == nums[i-1]){
        continue;
    }
    for(let j = i + 1; j < nums.length - 2; j++){
        if(j > i + 1 && nums[j] == nums[j-1]){
            continue;
        }
        let l = j + 1, r = nums.length - 1;
        while(l < r){
            let sum = nums[i] + nums[j] + nums[l] + nums[r];
            if(sum == target){
                res.push([nums[i], nums[j], nums[l], nums[r]])
                while(l<r && nums[l] == nums[l+1]){
                    l++;
                }
                while(l<r && nums[r] == nums[r-1]){
                    r--;
                }
                l++;
                r--;
            }
            else if(sum < target){
                l++;
            }
            else if(sum > target){
                r--;
            }
        }
    }
}
return res;

};

Delete the penultimate N node of the list

Topic Description

Given a linked list, delete the reciprocal nth node of the linked list and return the head node of the linked list.

Explain:
The given n guarantee is valid.

Example

Given a list: 1 - > 2 - > 3 - > 4 - > 5, and n = 2.

When the penultimate node is deleted, the list becomes 1 - > 2 - > 3 - > 5.

Answer

This problem is not difficult, you can traverse directly once, get the length of the list, and then traverse to the corresponding node again, delete directly.
You can also traverse once to make a one-way list a two-way list, and then delete it directly. This paper adopts the second approach.

var removeNthFromEnd = function(head, n) {
    let cur = head;
    while(cur.next){
        cur.next.prev = cur;
        cur = cur.next;
    }
    if(n == 1){
        // Delete the last node
        if(!cur.prev){
            return null;
        }
        else{
            cur.prev.next = null;
            return head;
        }
    }
    while(n > 0 && cur){
        if(n == 1){
            if(!cur.prev){
                // Delete the first node
                cur.next.prev = null;
                return cur.next
            }
            else{
                cur.prev.next = cur.next;
                cur.next.prev = cur.prev;
                return head;
            }
        }
        cur = cur.prev;
        n--;
    }
};

Effective parentheses

Topic Description

Given a string that only contains'(',')','{','}','[',']', determine whether the string is valid.

Valid strings need to satisfy:
The left parentheses must be closed with the same type of right parentheses.
The left parentheses must be closed in the correct order.
Note that empty strings can be considered valid strings.

Example

Input: "()"
Output: true
Input: "()[]{}"
Output: true
Input: "(]"
Output: false
Input: "([)]"
Output: false
Input: "{[]}"
Output: true

Answer

This is a simple problem. Maintain a stack directly and traverse the string. If the left side is on the stack, the right side is on the stack. If the element of the stack matches the traversed string, it will continue. Otherwise, return false.

var isValid = function(s) {
    if(s.length == 0){
        return true;
    }
    let stack = [];
    for(let i = 0; i < s.length; i++){
        if(s[i] == "(" || s[i] == "{"  || s[i] == "["){
            // Left parentheses, stack
            stack.push(s[i]);
        }
        else if(s[i] == ")" || s[i] == "}" || s[i] == "]"){
            let char = stack.pop();
            if((char == "(" && s[i] == ")") || (char == "{" && s[i] == "}") || (char == "[" && s[i] == "]")){
                continue
            }
            else{
                return false
            }
        }
    }
    if(stack.length == 0){
        return true
    }
    else{
        return false;
    }
};

Summary

My younger brother is ignorant of learning and has some incorrect or better practices. I hope you gods will correct and make suggestions, and I will continue to update them.

Posted by BrandonRoy on Tue, 13 Aug 2019 20:36:39 -0700