The front entry threshold is low and the personnel are uneven

The front end is about writing pages

People on the front end don’t understand data structures or algorithms


background

I believe you will often hear similar words in the community

Due to the front end to fit more quickly, and development at ordinary times when most of the writing is the business logic and interaction, often lead to us by some backend researchers’ contempt ‘, this is undoubtedly front-end developer is not fair for us, the front-end technology update iterative soon, and knowledge point trivial, want to learn the front-end is need certain continuous learning ability and creativity and curiosity, learn Getting a good front end is not an easy task.

We all know that programming = algorithm + data structure

Whether at the front end or the back end, as a developer to master these basic knowledge determines the development of your future technical path of the upper limit, algorithms and data structures for programmers is self-evident.

Putting aside some prejudices, we can’t deny that:

  1. There are many front-end students who do not have a deep understanding of data structure, and even some definitions of data structure types are not clear.
  2. There are limited data structures implemented with JS on the web.

In view of this actual situation, I will introduce the most common data structures in six blogs, and combine the classic original problems in LeetCode with JS methods to solve the actual problems, including:

  • The stack
  • The queue
  • The list
  • matrix
  • Binary tree
  • The heap

If you’re a front-end developer who wants to lay a solid foundation for data structures and can’t find the right resources online, xiaodi’s blog will definitely help you.

The stack (stack)

The definition of the stack

As the simplest kind of data structure, I think you all know something about stack. Let’s take a look at the definition of ‘stack’ on Baidu Encyclopedia



Data can only be added or removed from one end (the top of the stack). Again, the definition is very abstract, so let me give you an example of what I mean by ‘stack’.

The understanding of the stack



I’m using rainbow Wine, a popular wine on Tiktok, as an example:

If you go to the bar and order the rainbow, the bartender will bring you a clean, empty glass.

The rim is called the top of the stack, the bottom is called the bottom of the stack, and when he gives you this glass of wine he will

  1. First pour in the red ‘flaming lips ‘,
  2. Then the yellow ‘almond’ cocktail,
  3. And finally the blue Hawaii,

This is the one
Into the stackThe process of

And when you get this drink,

  1. You will first taste the refreshing blue banshee,
  2. And then the aroma of almonds,
  3. And at last intoxicated by the sea of red,

So this is one
Out of the stackIn the process.

Note: when the bartender makes a drink for you, he will only pour the wine into the glass from the rim. You will not make a hole in the bottom of the glass and pour the wine into your mouth.

It can only go in at the top of the stack, and it can only go out at the top of the stack, and that’s the limit in the definition above.

Js implements a simple stack

Array.prototype.push (array.prototype.pop); array.prototype.pop (array.prototype.pop); array.prototype.push (array.prototype.pop)

The following six lines of code correspond to the six procedures in the diagram

var arr = [2.7.1]
arr.push(8) 
arr.push(2)
arr.pop()
arr.pop()
arr.pop()Copy the code




How about that? Is that easy?

Let’s use the example on LeetCode to see what problems can be solved with stack data structures.

Example 1: Baseball game

Let’s look at the original address of the problem

You’re a baseball recorder now.


Given a list of strings, each string can be one of four types:


1.
The integer(Round score) : Directly represents the number of points you have earned in this round.


2.
"+"(Round score) : Indicates that the round score is the previous two rounds
effectiveThe sum of possessions scored.


3.
"D"(Round score) : Indicates that the round score is the previous round
effectiveDouble the number of points scored in the round.


4.
"C"(An operation, this is not a turn score) : indicates the last one you got
effectiveThe round score is invalid and should be removed.





Each round of operation is permanent and may affect the previous round and the next.


You need to return the sum of the points you scored in all rounds.


Example:

Input:"5"."2"."C"."D"."+"] Round 1: You can get 5 points. The sum is: 5. Round 2: You get 2 points. The sum is: 7. Operation 1: The data for round 2 is invalid. The sum is: 5. Round 3: You get 10 points (round 2 data has been deleted). The total is: 15. Round 4: You get 5 + 10 = 15 points. The total is: 30.Copy the code

Analyze the question:

You pass in an array, calculate the true score based on the different types of strings for each item in the array, and sum the results.

According to the data structure of “stack”, we can solve it in the following steps:

  1. Start by creating an empty array A(the empty stack) to hold the real score
  2. It then iterates through the array B passed in and calculates the score for each round based on the different types of each of its items
  • If the entry is of the first three types (‘ positive ‘, ‘+’, ‘D’), the round score is calculated as required and inserted into the empty array A (pushed)
  • If the item is of A fourth type (‘C’), the last item of array A is thrown (out of the stack)

3. Iterate and sum array A

The code is as follows:

export default (arr) => {  
    // Create an empty stack to save the result
        let result = []  
    // Data from the previous round
        let pre1  
    // Last wheel data
        let pre2  
    // Iterate over the array passed in to process the score
    arr.forEach(item= > {    
        switch (item) {      
            case 'C':        
                if (result.length) {          
                    result.pop()        
                }        
                break      
            case 'D':        
                pre1 = result.pop()        
                result.push(pre1, pre1 * 2)       
                break      
            case '+':       
                pre1 = result.pop()       
                pre2 = result.pop()      
                result.push(pre2, pre1, pre2 + pre1)      
                break     
            default:
                // *1 converts item to number
                result.push(item * 1)}})// Use reduce to sum
     return result.reduce((prev, cur) = >  prev + cur )}Copy the code

Example number two: Maximum rectangle

The original address

Given a two-dimensional binary matrix containing only 0 and 1, find the largest rectangle containing only 1 and return its area.


Example:

Input: [["1"."0"."1"."0"."0"],
  ["1"."0"."1"."1"."1"],
  ["1"."1"."1"."1"."1"],
  ["1"."0"."0"."1"."0"] output: 6Copy the code

Implementation idea:

Convert the index range of 2 or more consecutive 1s for each entry of the two-dimensional array ARR1 into a new two-dimensional array arR2, as shown in the following figure

[['1'.'1'.'0'.'1'.'1'],
    ['1'.'1'.'1'.'1'.'1'],
    ['1'.'1'.'0'.'1'.'1']]Copy the code

Can be converted to:

[[0,1],[3,4]], [[0,4]], [[0,1],[3,4]]Copy the code

So let’s write a function that looks for the intersection of two adjacent items in a two-dimensional array. It takes two parameters: the array to ask for the intersection and the number of rows that have been traversed.

Internally, the function is implemented like this:

The function pushes out the last two items of the received array (out of the stack twice), then traverses the two items to get the intersection,

  • If there is an intersection, it pushes the intersection onto the stack, recursively passing in the array and n
  • If there is no intersection, the last item of the array is removed (out of the stack), and the new array is passed to the function

More comments are written in the code, and I will send out the source code for your reference

export default arr => {
  // Use to store the two-dimensional array after processing
  let changeArr = []
  // The incoming two-dimensional array is iterated over the index position of successive 1s for each item
  arr.forEach((item, i) = > {
    // Index of each item
    let itemArr = []    
    let str = item.join(' ')    
    let reg = /1{2,}/g
    // The matching result of consecutive 1
    let execRes = reg.exec(str)
    // If not null, the match continues
    while (execRes) {
      // push the start and end positions of group j1 matched by item I
      itemArr.push([execRes.index, execRes.index + execRes[0].length - 1])      
      execRes = reg.exec(str)    
    }
    // Push the matching result of item I in
    changeArr.push(itemArr)  
  })
  // Save the area
  let area = []  
  // take the intersection function
  let find = (arr, n = 1) = > {    
      // Shallow-copy arR arrays prevent the function from being changed each time it is executed due to references
      let copyArr = [].concat(arr)    
      // The last item in the array
      let last = copyArr.pop()    
      // The penultimate item of the array
      let next = copyArr.pop()
      // Each of the last and penultimate terms
      let lastItem, nextItem
      // Get the intersection array
      let recuArr = []
      // as a temporary variable for each intersection fetched
      let item = []
      // The number of rows traversed
      n++
      // set the intersection of each interval of each adjacent term
      for (let i = 0; i < last.length; i++) {      
          lastItem = last[i]      
          for (let j = 0; j < next.length; j++) {        
            nextItem = next[j]        
            // start fetching the intersection
            // If there is an intersection
            if(! (Math.max(... lastItem) <=Math.min(... nextItem) ||Math.max(... nextItem) <=Math.min(... lastItem))) { item = [Math.max(lastItem[0], nextItem[0]), Math.min(lastItem[1], nextItem[1])]          
                recuArr.push(item)
            // Find the area of the intersection and push the area
            area.push((item[1] - item[0] + 1) * n)        
            }      
         }    
      }    
      // If there is no intersection in all cases, return false
      if (recuArr.length === 0) {
         return false
      } else {
         // If there is an intersection, continue recursively
         if (copyArr.length > 0) {
           copyArr.push(recuArr)
           find(copyArr, n)
         }
      }
    }
    // Decrement the array all the way, looking for an intersection for each row as the first row
    while (changeArr.length > 1) {
        find(changeArr)
        changeArr.pop()
    }
    // Returns the maximum value of the rectangular array that holds the area
    return area.length === 0 ? 0 : Math.max(... area) }Copy the code

reference

  1. Baidu encyclopedia
  2. “Js Data Structure and Algorithm” by Teacher Yin Guohui, head of video architecture front end of Toutiao
  3. leetCode

conclusion

As a relatively simple data structure, stack in JS is very common, is also easier to understand, we can use JS native array API can be implemented.

In the next article, I’ll show you how to use queues.