JavaScript Coding Test Course, Finding the Largest Palindrome

In this article, we will address the algorithm problem of finding the Catalan numbers using JavaScript. Catalan numbers are related to mathematical concepts such as structural concepts like nested parentheses, and this problem often appears in programming interviews. Therefore, we will explore a way to thoroughly understand and solve this problem.

What are Catalan numbers?

Catalan numbers are strings of length N composed of 0s and 1s that follow the following rules:

  • The first and last characters of the string must be 0.
  • The number of 1s in the string must always be at least 1, there cannot be consecutive 1s, and each 1 must be surrounded by 0s.

For example, the Catalan numbers of length 5 include 00000, 01000, 00100, 00010, 00001,
01010, 01100, 10000, etc. Catalan numbers are similar to the Fibonacci sequence, and
they can take different counts depending on the length N.

Problem Description

Given a natural number N, the problem is to output the count of Catalan numbers of length N.
For example, when N = 5, we need to find the number of Catalan numbers,
and the result should be 8.

Solution

To find the Catalan numbers, we can use recursive calls or dynamic programming (DP) methods.
Below is the formula for computing the Catalan numbers.

  • p(n) = p(n-1) + p(n-2) (n ≥ 2, p(0) = 1, p(1) = 1)

This formula recursively computes the Catalan numbers.
It is important to note that it should return 1 when n is 0.
Moreover, the relationship between p(n-1) and p(n-2) refers to the counts of previous Catalan numbers.

Algorithm Implementation

        
            // Function to calculate Catalan numbers in JavaScript.
            function countCatalanNumbers(n) {
                // Array to store Catalan numbers
                const dp = new Array(n + 1).fill(0);
                dp[0] = 1; // Case for length 0
                dp[1] = 1; // Case for length 1

                // Using dynamic programming to calculate the Catalan numbers.
                for (let i = 2; i <= n; i++) {
                    dp[i] = dp[i - 1] + dp[i - 2];
                }

                return dp[n]; // Return the count of Catalan numbers of length n.
            }

            // Example of function call
            const n = 5; // Value of N
            console.log(`The number of Catalan numbers of length ${n} is: ${countCatalanNumbers(n)}`);
        
        

Process Explanation

  1. Understanding the Problem: This is a problem to find the Catalan numbers for a natural number N.
  2. Dynamic Programming Approach: We define the Catalan numbers structurally.
  3. Array Initialization: Create the dp array and set the base values.
  4. Executing the Loop: Calculate and store the count of Catalan numbers in the array.
  5. Verifying the Result: Validate that the output of the function is correct.

Execution Result

        
            // Input: N = 5
            // Output: The number of Catalan numbers of length 5 is: 8
        
    

Conclusion

We have learned how to find the Catalan numbers and have been able to efficiently solve the problem through dynamic programming.
This problem frequently appears in programming interviews, so it is important to develop the ability to understand and implement the principles of the algorithm.

JavaScript Coding Test Course, Understanding Friend Relationships

Coding tests often include problems related to data structures and algorithms. In particular, problems related to identifying friendships are related to graph theory, and many companies use these problems to evaluate candidates’ logical thinking and coding skills.

Problem Description

The algorithm problem for identifying friendships is as follows.
Problem: Friend Relationship Exploration
Given the number of people N and M pairs representing friend relationships, write a function to determine the number of people who are not friends with a specific individual.

Input Format

  • First line: Number of people N (1 ≤ N ≤ 100)
  • Second line: Number of friend relationships M (1 ≤ M ≤ 1000)
  • Third line: M pairs of friend relationships provided in the form (a b), meaning a and b are friends.
  • Fourth line: Specific individual X (1 ≤ X ≤ N) – the individual to check friendships for

Output Format

Output the number of people who are not friends with the input individual X.

Example Input

    5
    4
    1 2
    1 3
    2 4
    4 5
    1
    

Example Output

    3
    

Problem Solving Process

Step 1: Understanding and Analyzing the Problem

To understand the given problem, we need to be able to represent the provided friend relationships as a graph. To do this, we will use an adjacency list. This method allows us to connect each individual with their friends and easily understand the relationships.

Step 2: Designing Data Structures

Each individual can store friend relationships through array indices. For example, to save individuals who are friends with individual 1, we will add the relative individual’s number to the adjacency list. This structure allows us to easily find friends of a specific individual.

Step 3: Designing the Algorithm

To calculate the number of people who are not friends, we follow these procedures:

  1. Check the friend relationships for all individuals (from 1 to N) to build a friend list.
  2. Refer to the friend list of the specific individual X to calculate the number of people who are not friends.
  3. Finally, declare a friendCount variable, and by subtracting the number of friends and X from the total number of individuals, we can obtain the number of people who are not friends.

Step 4: JavaScript Implementation


    function countNonFriends(N, M, relations, X) {
        // Create adjacency list
        const friends = Array.from({ length: N + 1 }, () => []);

        // Add relationships
        relations.forEach(([a, b]) => {
            friends[a].push(b);
            friends[b].push(a);
        });

        // Count the number of non-friends
        const friendSet = new Set(friends[X]);
        let count = 0;

        for (let i = 1; i <= N; i++) {
            if (i !== X && !friendSet.has(i)) {
                count++;
            }
        }

        return count;
    }
    
    const N = 5;
    const M = 4;
    const relations = [[1, 2], [1, 3], [2, 4], [4, 5]];
    const X = 1;
    console.log(countNonFriends(N, M, relations, X)); // 3
    

Step 5: Time Complexity Analysis

The time complexity of this algorithm is O(N + M) in the process of checking each friend relationship. This is efficient since each relationship is only explored once.

Conclusion

This problem provides an opportunity to learn the process of solving graph-related problems and understanding friend relationships. Additionally, it offers practice in managing data using arrays and objects in JavaScript, and in implementing algorithms. It is important to practice multiple problems of this type while preparing for coding tests.

JavaScript Coding Test Course, Find Cities at a Specific Distance

Hello, everyone! Today we will discuss an algorithm problem to find cities at a specific distance using JavaScript. This problem is one of the frequently featured topics in coding tests, where you will learn how to apply graph traversal and BFS (Breadth-First Search) techniques.

Problem Description

Write a function that returns a list of cities located at a specific distance starting from the given two vertices. The cities are connected by edges, and it is assumed that the distance calculation for each edge is equal to 1.

Input

  • n: the number of cities (1 ≤ n ≤ 300,000)
  • edges: the edges connecting each city, given as a 2D array. edges[i] = [a, b] means city a is directly connected to city b.
  • start: the city from which the distance calculation will start (1 ≤ start ≤ n)
  • distance: a specific distance k (0 ≤ distance ≤ n)

Output

Return an array of cities that are at a specific distance, sorted in ascending order. If there are no such cities, return an empty array.

Problem Solving Strategy

The key to this problem is exploring the graph using the BFS algorithm. BFS is a technique that can explore all vertices in a graph and is suitable for finding the shortest path.

The basic steps to solve the problem are as follows:

  1. Define the graph structure using the given edges array.
  2. Calculate the distance from the given start city to each city using BFS.
  3. Collect the cities whose distance matches the specific distance.
  4. Sort the resulting city list in ascending order and return it.

Implementation Steps

Step 1: Graph Structuring

We will use an adjacency list to hold the connection information between cities. This will be composed of an object where each city is the key and the list of connected cities is the value.

Step 2: Implementing BFS Algorithm

Using BFS, we will calculate the distance from the starting city to each city and find the cities that can be reached at a specific distance.

Step 3: Processing and Returning Results

Collect the cities that match the specific distance, sort them, and return the result.

JavaScript Code Implementation


function findCitiesAtDistance(n, edges, start, distance) {
    // Step 1: Create the graph
    const graph = Array.from({ length: n + 1 }, () => []);
    for (const [a, b] of edges) {
        graph[a].push(b);
        graph[b].push(a); // Add to both sides for a bidirectional graph
    }
    
    // Step 2: Set variables for BFS
    const queue = [];
    const distances = Array(n + 1).fill(-1); // Initialize distances
    distances[start] = 0;
    queue.push(start);
    
    // Perform BFS traversal
    while (queue.length > 0) {
        const currentCity = queue.shift();
        
        for (const neighbor of graph[currentCity]) {
            // If the city has not been visited
            if (distances[neighbor] === -1) {
                distances[neighbor] = distances[currentCity] + 1;
                queue.push(neighbor);
            }
        }
    }
    
    // Step 3: Find cities at a specific distance
    const result = [];
    for (let city = 1; city <= n; city++) {
        if (distances[city] === distance) {
            result.push(city);
        }
    }

    // Sort in ascending order
    result.sort((a, b) => a - b);
    return result;
}
    

Code Explanation

The code above is a function that finds cities at a specific distance according to the given requirements. I will explain each step:

Graph Creation

We create the graph structure by iterating through the edges array and storing the connection information between each city. An adjacency list is used to keep the list of cities connected to each city.

BFS Implementation

This is the process of calculating distance values using BFS from the starting city. We use a distances array to record the distances of each city, marking visited cities as -1 to prevent duplication.

Result Processing

After exploring all the cities, we add the cities that match the specific distance to the result list and finally sort them in ascending order before returning.

Test Cases

Now let’s check the operation of the implemented code through some test cases.


console.log(findCitiesAtDistance(6, [[3, 6], [4, 3], [3, 2], [1, 3], [1, 2], [2, 4]], 5, 2)); 
// Output: [4, 5, 6]
console.log(findCitiesAtDistance(4, [[1, 2], [1, 3], [2, 4]], 1, 2)); 
// Output: [4]
console.log(findCitiesAtDistance(5, [[1, 2], [1, 3], [1, 4], [2, 5]], 1, 1)); 
// Output: [2, 3, 4]
console.log(findCitiesAtDistance(7, [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]], 1, 3)); 
// Output: [4]
console.log(findCitiesAtDistance(3, [], 1, 1)); 
// Output: []
    

Conclusion

In this post, we covered an algorithm problem to find cities at a specific distance and explained the basic principles of graph traversal using BFS. Through this problem, we learned various concepts such as graph structuring, BFS implementation, and result processing. Since such problems are frequently presented in coding tests, understanding and practicing them is important. Next time, we will tackle more complex graph problems. Thank you!

JavaScript Coding Test Course, Longest Common Subsequence

Problem Description

Given two strings, the problem is to find the Longest Common Subsequence (LCS) of these two strings.
The longest common subsequence refers to the maximum length of the substring that overlaps while maintaining the order of the two strings.
For example, if string A is “ABCBDAB” and string B is “BDCAB”, the longest common subsequence can be “BDAB” or “BCAB”, etc.

Input Format

– The first line contains the length N of string A and the length M of string B. (1 ≤ N, M ≤ 1000)
– The second line contains string A.
– The third line contains string B.

Output Format

– Output the length of the longest common subsequence of the two strings.

Example

            Input:
            7 5
            ABCBDAB
            BDCAB

            Output:
            4
        

Approach to Solve the Problem

This problem is a typical example of Dynamic Programming.
To find the LCS, we compare the two strings to find matching characters,
solving the subproblems at that point to derive the final length.

Step-by-Step Approach

  1. Initialize the Dynamic Programming Table:

    Create a 2D array DP. DP[i][j] stores the length of the longest common subsequence
    of the first i characters of string A and the first j characters of string B. The size of the array is (N+1) x (M+1).

  2. Fill the Table:

    If the i-th character of A and the j-th character of B are the same, then DP[i][j] = DP[i-1][j-1] + 1.
    Otherwise, set DP[i][j] = max(DP[i-1][j], DP[i][j-1]).

  3. Output the Result:

    By reaching DP[N][M], we can return the length of the longest common subsequence.

JavaScript Code


function longestCommonSubsequence(A, B) {
    const N = A.length;
    const M = B.length;
    
    // Initialize the DP table
    const DP = Array.from(Array(N + 1), () => Array(M + 1).fill(0));
    
    // Fill the DP table
    for (let i = 1; i <= N; i++) {
        for (let j = 1; j <= M; j++) {
            if (A[i - 1] === B[j - 1]) {
                DP[i][j] = DP[i - 1][j - 1] + 1;
            } else {
                DP[i][j] = Math.max(DP[i - 1][j], DP[i][j - 1]);
            }
        }
    }
    
    return DP[N][M];
}

// Run the input example
const A = 'ABCBDAB';
const B = 'BDCAB';
console.log(longestCommonSubsequence(A, B)); // Output: 4
        

Review and Practice Problems

If you have fully understood this problem, try to enhance your skills with additional practice problems. Challenge yourself with the following problems:

  • A problem to find the longest common subsequence among three given strings instead of two.
  • A problem to find the longest common subsequence without distinguishing between uppercase and lowercase letters.
  • A problem to output all possible combinations that derive the longest common subsequence.

Conclusion

The longest common subsequence problem is one of the important concepts in computer science and can be applied to various algorithm problems.
Solving this problem using Dynamic Programming will help tackle more complex problems. Practice by solving various problems!

JavaScript Coding Test Course, Understanding Geometry

Coding tests have become a mandatory process for many companies these days. In particular, JavaScript is a programming language widely used in web development, and solving geometric problems greatly aids in understanding algorithms. In this article, we will introduce a geometric algorithm problem that can be solved with JavaScript and explain the solution process in detail.

Problem Description

The following is a problem of determining whether two points are inside a given rectangle.

Problem: Determine if Points are Inside a Rectangle

The coordinates of the bottom-left corner of the given rectangle are (x1, y1), and the coordinates of the top-right corner are (x2, y2). Additionally, there are two points A(xA, yA) and B(xB, yB). Write a function to determine whether these points are inside the rectangle.

Input

  • Bottom-left corner of the rectangle: (x1, y1)
  • Top-right corner of the rectangle: (x2, y2)
  • Point A: (xA, yA)
  • Point B: (xB, yB)

Output

Write a function that returns true if each point is inside the rectangle, and false otherwise. If both points are inside, return true; otherwise, return false.

Solution Process

Now let’s go through the steps to solve this problem.

Step 1: Understanding the Problem

We have the coordinates of the rectangle’s corners and need to verify the coordinates of each point. The conditions for being inside the rectangle are as follows:

  • x1 < xA < x2
  • y1 < yA < y2
  • x1 < xB < x2
  • y1 < yB < y2

Each point must satisfy all the above conditions to be considered inside the rectangle.

Step 2: Writing the Function

Here is the JavaScript code based on this logic.


function isPointInsideRectangle(x1, y1, x2, y2, xA, yA, xB, yB) {
    const isAInside = (x1 < xA && xA < x2) && (y1 < yA && yA < y2);
    const isBInside = (x1 < xB && xB < x2) && (y1 < yB && yB < y2);
    
    return isAInside && isBInside;
}

// Test
const result = isPointInsideRectangle(0, 0, 10, 10, 5, 5, 5, 5); // true
console.log(result);
    

Step 3: Testing and Verification

Let’s test the function. We confirmed that when the bottom-left corner of the rectangle is (0, 0) and the top-right corner is (10, 10), the point (5, 5) is inside.

In the example above, both points are the same (5, 5), so the function returns true. However, it should return false if one point is outside the rectangle.

Step 4: Checking Various Cases

We can validate the function through various cases. Here are additional test examples.


// Case 1: Both points are inside
console.log(isPointInsideRectangle(0, 0, 10, 10, 1, 1, 2, 2)); // true

// Case 2: Only one point is inside
console.log(isPointInsideRectangle(0, 0, 10, 10, 1, 1, 11, 11)); // false

// Case 3: Both points are outside
console.log(isPointInsideRectangle(0, 0, 10, 10, -1, -1, 11, 11)); // false

// Case 4: Located on the edge of the rectangle
console.log(isPointInsideRectangle(0, 0, 10, 10, 0, 5, 5, 10)); // false
    

Conclusion

Now we have completed the function to determine whether the points are inside a given rectangle using JavaScript. Problems like these are great for developing algorithmic thinking and are frequently presented in coding tests.

I hope this article helped you understand the basics of geometric problems and how to apply them. Continue to challenge yourself with various algorithmic problems!