LEETCODE (1-10) OF JS ALGORITHM PROBLEMS

Posted by redgtsviper on Mon, 12 Aug 2019 09:17:04 +0200

Preface

For a long time, the knowledge reserve of front-end development is temporary at the data structure and algorithm level, which may be attributed to the business nature of our front-end development, but I think any programming position can not do without data structure and algorithm.
Therefore, as a front-end vegetable chicken, I intend to do a column about using JavaScript to solve algorithm problems, will keep up with the new, I hope you urge. At the same time, I am a little ignorant of learning, the content of the article may be wrong, I hope you gods pointed out, thank you.
no more bb, show me the code!

Topics come from leetcode

The sum of two numbers

Topic Description

Given an array of integers nums and a target value, you can find the two integers that sum to the target value in the array and return their array subscripts.

Example

Given nums = 2, 7, 11, 15], target = 9

Because nums[0] + nums[1] = 2 + 7 = 9
So go back [0, 1]

Answer

It's not a difficult problem. Traverse nums, subtract the current element from the targer, and if the element is in the array, it's done. However, it should be noted that the unified element can not be used twice.

var twoSum = function(nums, target) {
    let idx1, idx2;
    nums.forEach((ele, index) => {
        let tempIdx = nums.indexOf(target - ele);
        if(tempIdx !== -1 && tempIdx !== index){
            idx1 = index;
            idx2 = tempIdx;
        }
    });
    return [idx1, idx2]
};

The sum of two numbers

Topic Description

Two non-empty linked lists are given to represent two non-negative integers. Among them, their respective digits are stored in reverse order, and each of their nodes can only store one digit.
If we add the two numbers together, we return a new list to represent their sum.
You can assume that neither of these numbers will begin with zero except the number 0.

Example

Input: (2 - > 4 - > 3) + (5 - > 6 - > 4)
Output: 7 - > 0 - > 8
Cause: 342 + 465 = 807

Answer

This problem is not difficult, but a little complicated, involving the list, while examining the operation of the large number of js.
First traverse the two linked lists to get the corresponding numbers, then add them together, and finally back-calculate the corresponding linked list of the results.

function ListNode(val) {
      this.val = val;
      this.next = null;
    return {
        val: this.val,
        next: null
    }
}

function addBigNumber(a, b) {
  var res = '',
    temp = 0;
  a = a.split('');
  b = b.split('');
  while (a.length || b.length || temp) {
    temp += ~~a.pop() + ~~b.pop();
    res = (temp % 10) + res;
    temp = temp > 9;
  }
  return res.replace(/^0+/, '');
}

var addTwoNumbers = function(l1, l2) {
    let num1 = '', num2 = '', cur;
    cur = l1;

    while(cur){
        num1 += cur.val.toString();
        cur = cur.next;
    }
    cur = l2;
    while(cur){
        num2 += cur.val.toString();
        cur = cur.next;
    }
    num1 = num1.split('').reverse().join('');
    num2 = num2.split('').reverse().join('');
    
    let total;
    if(num1.length > 21 || num2.length > 21){
        total = addBigNumber(num1, num2)
    }
    else{
        total = Number(num1) + Number(num2)
    }

    total = total.toLocaleString().toString().split('').reverse().join('').replace(/,/g, '')
    console.log(num1, num2, total)
    
    let l3 = ListNode(total[0]);
    cur = l3;
    for(let i = 1; i < total.length; i++){
        let node = ListNode(total[i]);
        cur.next = node;
        cur = node;
    }

    return l3;
};

The longest substring without duplicate characters

Topic Description

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

Example

Input: "abcabcbb"
Output: 3
Interpretation: Because the longest substring without duplicate characters is "abc", its length is 3.

Input: "bbbbb"
Output: 1
Interpretation: Because the longest substring without duplicate characters is "b", its length is 1.

Input: "pwkew"
Output: 3
Interpretation: Because the longest substring without duplicate characters is "wke", its length is 3.

Note that your answer must be the length of the substring, "pwke" is a subsequence, not a substring.

Answer

Maintain an array to store non-repetitive substrings and traverse the input string. If the current character is not in the non-repetitive array, add it. Otherwise, the non-repetitive array is empty and push the current character.
At the same time, another longest non-repetitive substring array is maintained.

var lengthOfLongestSubstring = function(s) {
    let max = 0, maxArr = [], oldArr= [];
    s.split('').forEach((ele, index) => {
        if(maxArr.indexOf(ele) === -1){
            maxArr.push(ele)
            if(maxArr.length > max){
                max = maxArr.length;
            }
        }
        else{
            maxArr = [ele]
            let tempItem = oldArr.pop();
            while(tempItem != ele){
                maxArr.unshift(tempItem)
                tempItem = oldArr.pop();
            }
        }
        oldArr = [...maxArr]
    })
    return max;
};

Finding the Median of Two Ordered Arrays

Topic Description

Given two ordered arrays of size m and n, nums1 and nums2.

Please find the median of these two ordered arrays and ask the time complexity of the algorithm to be O (log (m + n).

You can assume that nums1 and nums2 are not empty at the same time.

Example

nums1 = [1, 3]
nums2 = [2]
The median is 2.0.

nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

Answer

Combine the two numbers and sort them, then get the median. The question is how to rank them when the time complexity is limited to O (log (m + n)?
We directly use sort() method here. The underlying principle of this method is to integrate multiple sorting methods. Different sorting methods are selected according to the length of the array. With the optimization of V8 engine, the time complexity can be satisfied.
It's a bit like sneaking around a dog...
Source code of sort method: Array API source code Let's start with line 710.

var findMedianSortedArrays = function(nums1, nums2) {
    let num = nums1.concat(nums2);
    num = num.sort((a, b) => a - b);
    let mid = Math.floor(num.length / 2);
    if (num.length % 2 === 0) {
        return (num[mid-1] + num[mid])/2
    } else {
        return num[mid]
    }
};

Longest Palindromic Substring

Topic Description

Given a string s, find the longest palindrome substring in S. You can assume that the maximum length of S is 1000.

Example

Input: "babad"
Output: "bab"
Note: "aba" is also an effective answer.

Input: "cbbd"
Output: "bb"

Answer

This problem needs to be solved by dynamic programming. First, we can judge whether all substrings of length 1,2,3 are palindromes or not.
The length of the palindrome is 1.
The length is 2 or 3, depending on whether the first character is the same.
The length is greater than 3, depending on whether the substring palindromes after removing the first character, and whether the first character is the same.
The core lies in DP [i] [j]== DP [i + 1] [j-1] & s [i]==== s [j]

var longestPalindrome = function(s) {
    let dp = [];
    for(let i = 0; i < s.length; i++){
        dp[i] = [];
    }

    let max = -1, str = '';
    for(let k = 0; k < s.length; k++){
        // k is the traversal length of the substring - 1, that is, the distance from the left subscript to the right subscript
        for(let i = 0; i + k < s.length; i++){
            let j = i + k;
            // i is the left subscript at the beginning of the substring and j is the right subscript at the beginning of the substring
            if(k == 0){
                // When the length of substring is 1, it must be palindrome
                dp[i][j] = true;
            }
            else if(k <= 2){
                // When the length of the substring is 2, the two characters with the same character are palindrome, the length is 3, and the first character with the same character is palindrome.
                if(s[i] == s[j]){
                    dp[i][j] = true;
                }
                else{
                    dp[i][j] = false;
                }
            }
            else{
                // When the length of the substring exceeds 3, it depends on whether the substring after the end of the head is palindromic and whether the first character is the same.
                if(dp[i+1][j-1] && (s[i] == s[j])){
                    dp[i][j] = true;
                }
                else{
                    dp[i][j] = false;
                }
            }

            if(dp[i][j] && k > max){
                max = k;
                str = s.substring(i, j + 1)
            }
        }
    }

    return str;
};

Z-transformation

Topic Description

Arrange a given string in Z glyph from top to bottom and left to right according to the number of rows given.
For example, when the input string is "LEETCODEISHIRING" and the number of rows is 3, it is arranged as follows:

L   C   I   R
E T O E S I I G
E   D   H   N

Later, your output needs to be read from left to right, line by line, to produce a new string, such as "LCIRETOESIIGEDHN".
Please implement this function that converts a string to a specified number of rows:
string convert(string s, int numRows);

Example

Input: s = LEETCODEISHIRING, numRows = 3
Output: "LCIRETOESIIGEDHN"

Input: s = LEETCODEISHIRING, numRows = 4
Output: "LDREOEIIECIHNTSG"
Explanation:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

Answer

The structure of this topic is somewhat strange, but there are also rules to follow. We find that the character order of this "Z" is as follows: vertical down, oblique up, and then vertical down.
In fact, we can simplify the structure directly into a two-dimensional array, remove the space in the middle, and then traverse line by line to get the answer.
Such as:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

Can become

L D R
E O E I I
E C I H N
T S G

Then read it line by line and spell it into a string.

var convert = function(s, numRows) {
    if(numRows == 1){
        return s;
    }

    let arr = [], direction = 'down', line = 0, str = '';
    for(let i = 0; i < numRows; i++){
        arr[i] = [];
    }

    for(let i = 0; i < s.length; i++){
        arr[line].push(s[i]);

        if(line == 0){
            line++;
            direction = 'down'
        }
        else if(line == numRows - 1){
            line--;
            direction = 'up'
        }
        else{
            if(direction == 'down'){
                line++;
            }
            else if(direction = 'up'){
                line--;
            }
        }
    }

    for(let i = 0; i < numRows; i++){
        str += arr[i].join("");
    }

    return str;
};

Integer inversion

Topic Description

Given a 32-bit signed integer, you need to reverse the number on each bit of the integer.
Be careful:
Assuming that our environment can only store 32-bit signed integers, the numerical range is [231, 231_1]. Based on this assumption, return 0 if the integer overflows after inversion.

Example

Input: 123
Output: 321

Input: -123
Output: -321

Input: 120
Output: 21

Answer

This is a simple question, but we need to consider the edge spillover.

var MAX = Math.pow(2, 31) - 1
var MIN = -1 * Math.pow(2, 31)

var reverse = function(x) {
    let str = x.toString().split(''), symbolFlag = false;
    if(str[0] == '-'){
        symbolFlag = true;
        str.shift();
    }

    str = str.reverse();

    if(symbolFlag){
        str.unshift('-');
    }
    let num = Number(str.join(''))
    if(num < MIN || num > MAX){
        return 0
    }
    else{
        return num
    }
};

String Conversion Integer (atoi)

Topic Description

Please implement an atoi function that converts strings into integers.

First, the function discards the useless opening space character as needed until it finds the character with the first space.
When the first non-empty character we find is a positive or negative sign, we combine the symbol with as many consecutive digits as possible behind it as a positive or negative sign of the integer; if the first non-empty character is a number, we directly combine it with the consecutive digit characters to form an integer.
In addition to the valid integer part, the string may have redundant characters that can be ignored and should not affect the function.

Note: If the first non-space character in the string is not a valid integer character, the string is blank, or the string contains only blank characters, then your function does not need to be converted.
In any case, return 0 if the function cannot be converted effectively.

Explain:
Assuming that our environment can only store 32-bit signed integers, the numerical range is [231, 231_1]. If the value exceeds this range, qing returns INT_MAX (231_1) or INT_MIN (231).

Example

It's a long topic. That's all right. Let's look at the examples directly.

Input: "42"
Output: 42

Input: "-42"
Output: -42
Interpretation: The first non-blank character is'-', which is a negative sign.
We try to combine the minus sign with all the successive numbers that follow, and finally we get - 42.

Input: "4193 with words"
Output: 4193
Interpretation: The conversion ends with the number'3', because its next character is not a number.

Input: "words and 987"
Output: 0
Interpretation: The first non-empty character is'w', but it is not a number or a positive or negative sign.
Therefore, effective conversion cannot be performed.

Input: "-91283472332"
Output: - 2147483648
Interpretation: The number "-91283472332" exceeds the range of 32-bit signed integers.
So return INT_MIN (231).

Answer

It's not difficult, but there are many pits. First of all, we adopt ASCII encoding to determine whether characters are numeric or English or something else.
First remove the blanks, then take the first character, judge the positive and negative symbols, if the English directly returns to 0, if the number is not taken.
Traverse from the second character and exit the loop if it is not a number.
Finally, spillover should be considered.

const MIN = -1 * Math.pow(2, 31);
const MAX = Math.pow(2, 31) - 1;

var myAtoi = function(str) {
    str = str.trim();
    let result = '', symbol = '';
    let idx = 0;

    if(str.charCodeAt(0) === 45){
        idx++;
        symbol = '-';
    }
    else if(str.charCodeAt(0) === 43){
        idx++;
    }
    else if(str.charCodeAt(0) < 48 || str.charCodeAt(0) > 57){
        return 0;
    }

    for(let i = idx; i < str.length; i++){
        if(str.charCodeAt(i) === 46){
            break;
        }
        else if(str.charCodeAt(i) >= 48 && str.charCodeAt(i) <= 57){
            result += str[i];
        }
        else{
            break
        }
    }

    result = symbol.toString() + result.toString();

    if(Number(result) !== Number(result)){
        return 0;
    }
    else if(Number(result) < MIN){
        return MIN;
    }
    else if(Number(result) > MAX){
        return MAX;
    }
    else{
        return Number(result)
    }
};

Palindrome number

Topic Description

Determine whether an integer is a palindrome number. Palindrome numbers refer to integers that read in positive order (from left to right) and reverse order (from right to left).

Example

Input: 121
Output: true

Input: -121
Output: false
Explanation: Read from left to right at - 121. Read from right to left, 121-. So it's not a palindrome number.

Input: 10
Output: false
Explanation: Read from right to left, 01. So it's not a palindrome number.

Answer

It's a simple question. Inverse comparison is enough.

var isPalindrome = function(x) {
    let y = x.toString().split("").reverse().join("");
    return x == y
};

Regular Expression Matching

Topic Description

Give you a string s and a character rule p, and ask you to implement a regular expression match that supports'. 'and'*'.

'.'Matches any single character
'*'matches zero or more previous elements
The so-called matching is to cover the whole string s, not part of the string.

Explain:
s may be empty and contain only lowercase letters from a-z.
p may be empty and contain only lowercase letters from a-z, as well as characters. and *.

Example

Input:
s = "aa"
p = "a"
Output: false
Interpretation: "a" cannot match the entire string of "aa".

Input:
s = "aa"
p = "a*"
Output: true
Interpretation: Because'*'means that zero or more previous elements can be matched, where the former element is' a'. Therefore, the string "a a" can be considered'a'repeated once.

Input:
s = "ab"
p = ".*"
Output: true
Interpretation: "." means that zero or more ('') arbitrary characters ('.') can be matched.

Input:
s = "aab"
p = "cab"
Output: true
Interpretation: Because'*'means zero or more, here'c' is zero and'a'is repeated. So the string "aab" can be matched.

Input:
s = "mississippi"
p = "misisp*."
Output: false

Answer

This problem is a little complicated. We use a recursive method to compare two strings, only one character at a time.
The next character of the current recursive p is classified as * or not.
The next character of p is*
If the current character of s and p is the same or the current character of p is..., the result depends on:

isMatch(s.slice(1), p) || isMatch(s.slice(1), p.slice(2)) || isMatch(s, p.slice(2))

Returns true if the last two characters of p are. *.
If it does not meet the above two conditions, it will depend on

isMatch(s,p.slice(2))

The next character of p is not*
That's easy.
Returns true if the current character of s and p is the same or the current character of p is..
Otherwise return false

var isMatch = function(s, p) {
    if(s.length === 0 && p.length === 0){
        return true;
    }
    if(s.length !== 0 && p.length === 0){
        return false;
    }

    let str = s[0], pattern = p[0];
    let isNextStart = p[1] === "*";

    if(isNextStart){
        if(str && (str === pattern || pattern === ".")){
            return isMatch(s.slice(1), p) || isMatch(s.slice(1), p.slice(2)) || isMatch(s, p.slice(2))
        }
        else if(pattern === "." && p.slice(2).length === 0){
            return true
        }
        else{
            return isMatch(s,p.slice(2));
        }
    }
    else{
        if(str && (str === pattern || pattern === ".")){
            return isMatch(s.slice(1), p.slice(1))
        }
        else{
            return false;
        }
    }
};

summary

All the topics in this paper are from leetcode It's not the only way to do it, and there may even be some mistakes. I hope you gods point out that your brother is modest in learning.

Topics: Javascript Programming ascii encoding