Java Coding Test Course, Finding the Order of Building

In this article, we will solve an algorithm problem to prepare for a Java coding test. The topic is “Finding the Order of Building Construction.” This problem combines graph traversal algorithms and sorting algorithms that can be utilized in various fields. I will explain the theoretical background and code implementation methods needed to solve the problem in detail.

Problem Description

You are planning to construct several buildings in a city. Each building has an order based on its dependencies with one another. In other words, if building A must be constructed before building B, then the dependency is represented as A -> B. You need to solve the problem of determining the construction order of all buildings according to these rules.

Below is the number of buildings N and the dependency information given as input. You need to output the construction order of all buildings.
For example, let’s assume the following dependencies are given:

            5 4
            2 1
            3 1
            4 2
            5 3
            

This input indicates that there are 5 buildings and the following dependencies exist.
Building 1 must be constructed after building 2, building 1 after building 3, building 2 after building 4, and building 3 after building 5.
In this case, a possible construction order of the buildings could be:

            1, 2, 3, 4, 5 or 1, 2, 3, 5, 4, etc.
            

Strategy for Problem Solving

To solve this problem, we can utilize the concept of topological sorting from graph theory. Topological sorting is the act of arranging all vertices (nodes) in a directed graph according to the direction of the edges. In this case, if there is an edge A -> B, A must come before B.

The main steps of the algorithm are as follows:

  1. Implement the graph in the form of an adjacency list.
  2. Calculate the in-degree of each node.
  3. Add the nodes with an in-degree of 0 to a queue to start processing.
  4. While removing nodes from the queue, record the order and decrease the in-degree of the other connected nodes. If any node’s in-degree becomes 0, add it back to the queue.
  5. Repeat until all nodes are processed.

Java Implementation Code

Based on the algorithm described above, let’s implement the code in Java. Below is the Java code that performs topological sorting.

                
public class BuildingOrder {
    import java.util.*;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Receiving input for buildings and dependencies
        int N = scanner.nextInt(); // Number of buildings
        int M = scanner.nextInt(); // Number of dependencies
        
        List> graph = new ArrayList<>();
        int[] inDegree = new int[N + 1]; // In-degree
        
        for (int i = 0; i <= N; i++) {
            graph.add(new ArrayList<>());
        }
        
        for (int i = 0; i < M; i++) {
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            graph.get(a).add(b);
            inDegree[b]++;
        }
        
        // Implementing the process to perform topological sorting
        StringBuilder result = new StringBuilder();
        Queue queue = new LinkedList<>();

        // Adding nodes with in-degree of 0 to the queue
        for (int i = 1; i <= N; i++) {
            if (inDegree[i] == 0) {
                queue.offer(i);
            }
        }
        
        while (!queue.isEmpty()) {
            int current = queue.poll();
            result.append(current).append(" ");

            for (int neighbor : graph.get(current)) {
                inDegree[neighbor]--;
                if (inDegree[neighbor] == 0) {
                    queue.offer(neighbor);
                }
            }
        }

        // Outputting the result
        System.out.println("Construction order of buildings: ");
        System.out.println(result.toString().trim());
        scanner.close();
    }
}
                
            

The above code first receives the number of buildings and their dependencies, initializes the graph and in-degrees based on this input, and then determines the construction order through topological sorting and prints it.

Input and Output Examples

Example Input

            5 4
            2 1
            3 1
            4 2
            5 3
            

Example Output

            Construction order of buildings: 
            1 2 3 4 5 or 1 2 3 5 4
            

Advanced Learning

The topological sorting algorithm can be used in many real-world situations. For example, it is useful for project schedule management, grammar parsing in compilers, and solving problems with precedence relationships among multiple tasks. Understanding and effectively utilizing such algorithms can greatly aid in problem-solving not only for coding tests but also across various fields.

Practice Problems:

1. Use topological sorting to determine the construction order for the following graph.

2. Implement the following dependencies and visualize the graph to think about what issues might arise.

The problem of finding the order of building construction discussed in this article will enhance your understanding of Java programming and algorithms, and will be highly beneficial for applying this knowledge in real situations. Wishing you successful outcomes in your coding tests.

Java Coding Test Course, Creating a Blu-ray

Coding tests are becoming an increasingly important element in the field of software engineering. In this article, we will discuss how to acquire the skills necessary to solve complex algorithm problems using Java, focusing on the problem titled ‘Making Blu-rays.’

Problem Description

Requirements: Based on the given movie list and the playback times of each movie, find a way to use the minimum number of Blu-rays to play all movies, considering the capacity of a Blu-ray. The maximum capacity that can be held in one Blu-ray is specified.

Input:

  • maxSize: The maximum capacity of each Blu-ray (integer)
  • movies: A list of movie playback times (integer array)

Output:

  • The minimum number of Blu-rays required to play all movies (integer)

Example


maxSize: 10
movies: [1, 2, 3, 4, 5, 6]
Output: 3

Problem Approach

To solve this problem, we can approach it with the following steps:

  1. Consider adding as many movies as possible without exceeding the capacity of one Blu-ray.
  2. Sort the list of movies so that shorter movies are played first.
  3. Calculate the playback time of each Blu-ray and use a new Blu-ray if it exceeds the maximum capacity.
  4. Count the number of Blu-rays needed.

Java Code Implementation


import java.util.Arrays;

public class BluRayMaker {
    
    public static int minBluRays(int maxSize, int[] movies) {
        Arrays.sort(movies); // Sort the movies.
        int bluRayCount = 0;
        int currentBluRaySize = 0;

        for (int i = movies.length - 1; i >= 0; i--) {
            // Add the movie to the current Blu-ray.
            if (currentBluRaySize + movies[i] <= maxSize) {
                currentBluRaySize += movies[i];
            } else {
                // Use a new Blu-ray if the capacity is exceeded.
                bluRayCount++;
                currentBluRaySize = movies[i]; // Start the Blu-ray with the current movie.
            }
        }

        // Add to the count if there is a remaining Blu-ray.
        if (currentBluRaySize > 0) {
            bluRayCount++;
        }

        return bluRayCount;
    }

    public static void main(String[] args) {
        int maxSize = 10;
        int[] movies = {1, 2, 3, 4, 5, 6};
        System.out.println("Minimum number of Blu-rays needed: " + minBluRays(maxSize, movies));
    }
}

Code Explanation

The code above defines a class for creating Blu-rays and implements an optimal movie selection method. The code works as follows:

  1. Sort the movie list and process it from the longest movie onward.
  2. Add movies to the current Blu-ray without exceeding the maximum capacity.
  3. If the capacity is exceeded, finish the current Blu-ray and start a new one.
  4. After processing all movies, count the last Blu-ray if it exists.

Analysis and Complexity

The time complexity of this problem is O(N log N). This is due to the time required to sort the given movie list. An additional O(N) time is spent traversing the movie list once. The space complexity is O(1), as no additional data structures are required.

Conclusion

Learning how to approach and solve algorithm problems like this is very useful for preparing for coding tests. As these types of problems can frequently appear in practice, it is important to try solving a variety of challenges. “Making Blu-rays” is a good problem to practice, as it requires both a grasp of basic Java syntax and algorithm design skills.

In the next lesson, we will tackle more complex algorithm problems and provide answers to various questions you may encounter in real coding tests. Thank you!

Java Coding Test Course, Helping the Underprivileged

Hello. Today, we will tackle an algorithm problem related to helping the less fortunate through a coding testing course using Java. Helping the less fortunate refers to the activities that support neighbors in need. Through this problem, we will understand and implement the ‘assignment’ algorithm.

Problem Description

Three volunteers, Gasanho, Seonghoon, and Minjae, have decided to help the less fortunate at specified times. However, since each volunteer cannot help all the less fortunate alone, they must efficiently allocate their time.

Considering the following conditions, implement an algorithm that assigns volunteers to provide the most help to the less fortunate:

  • Number of volunteers: N (1 ≤ N ≤ 100)
  • Number of less fortunate: M (1 ≤ M ≤ 100)
  • Each volunteer can help a maximum of K less fortunate individuals.
  • An adjacency matrix representing the connection between volunteers and the less fortunate will be provided.

Input Format

The first line contains the number of volunteers N and the number of less fortunate M. The next N lines provide information about which less fortunate individuals each volunteer can help. A value of 1 indicates they can help, while 0 indicates they cannot.

Output Format

Print the number of volunteers who helped the most less fortunate individuals and the respective indices of the individuals they can assist.

Example Input

    3 4
    1 1 0 1
    1 0 1 1
    0 1 1 0
    

Example Output

    2
    1 2
    2 3
    

Problem Solving Process

To solve this problem, we can use search techniques such as DFS (Depth-First Search) or BFS (Breadth-First Search). Follow the steps below to design an algorithm to solve the assignment problem:

Step 1: Process Input Data

    Scanner sc = new Scanner(System.in);
    int N = sc.nextInt(); // Number of volunteers
    int M = sc.nextInt(); // Number of less fortunate
    int[][] graph = new int[N][M]; // Create adjacency matrix
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            graph[i][j] = sc.nextInt(); // Input adjacency matrix
        }
    }
    

Step 2: Assign Volunteers

Based on the situation where volunteers can help each less fortunate individual, use DFS to explore all possible combinations:

    boolean[] visited = new boolean[M]; // Check visit status
    int[] result = new int[N]; // Result array
    int[] assignment = new int[N]; // Volunteer assignment
    
    for (int i = 0; i < N; i++) {
        Arrays.fill(visited, false); // Initialize visit array
        assignVolunteerToNeighbour(i, graph, visited, assignment);
    }
    
    private static boolean assignVolunteerToNeighbour(int volunteer, int[][] graph, boolean[] visited, int[] assignment) {
        for (int neighbour = 0; neighbour < M; neighbour++) {
            if (graph[volunteer][neighbour] == 1 && !visited[neighbour]) {
                visited[neighbour] = true; 
                if (assignment[neighbour] == -1 || assignVolunteerToNeighbour(assignment[neighbour], graph, visited, assignment)) {
                    assignment[neighbour] = volunteer; 
                    return true;
                }
            }
        }
        return false;
    }
    

Step 3: Print Final Result

    for (int i = 0; i < N; i++) {
        if (assignment[i] != -1) {
            System.out.println((assignment[i] + 1) + " " + (i + 1));
        }
    }
    

Conclusion

Today, we implemented an algorithm to assign volunteers through a Java coding test problem related to helping the less fortunate. I hope this problem has helped deepen your understanding of graph theory and search algorithms. Additionally, I hope it has assisted you in practicing skills that can be directly applied in coding tests and work. I will return with a new algorithm problem in the next course. Thank you!

Java Coding Test Course, I Will Become the President of the Residents’ Association

In this article, we will look at one of the famous problems in Java coding tests, the “I Will Become the Apartment Manager” problem.
This problem serves as a good example to learn the basics of dynamic programming, and I will detail the process of solving the given problem through an efficient algorithm.

Problem Description

The goal of the “I Will Become the Apartment Manager” problem is as follows.

Problem:
Assume there are N floors and K apartments. Write an algorithm to calculate the number of people living in apartment N on the Kth floor.

Each apartment has a problem to find the number of people living in apartment N on the Kth floor. There is 1 person on the ground floor, and the number of people in apartment N on each floor is the sum of the number of people in all apartments on the floor below. Therefore,

  • 1st floor apartment 1 = 1
  • 1st floor apartment 2 = 1
  • 2nd floor apartment 1 = 1
  • 2nd floor apartment 2 = 1 + 1 = 2
  • 3rd floor apartment 1 = 1
  • 3rd floor apartment 2 = 1 + 2 = 3

This pattern emerges.

For the given K and N, please create a function that calculates the number of people living in that apartment.

Input and Output Format

Input: The first line gives the number of test cases T (1 ≤ T ≤ 14).
Each test case consists of two integers K and N (0 ≤ K ≤ 14, 1 ≤ N ≤ 14).
Output: For each test case, print the number of people living in apartment N on the Kth floor.

Problem Solving Process

Step 1: Understanding the Problem

The essence of the problem is to understand the pattern of the number of people from the ground floor to the Kth floor, and based on this pattern, to find the number of people in apartment N.
As I understand, the apartment problem can apply the rules of dynamic programming.
In other words, the value of apartment N on each floor can be defined as the sum of the values in apartments N and (N-1) on the previous floor.

Step 2: Designing the Dynamic Programming Table

To solve this problem, we will declare a 2D array to calculate the number of people in Kth floor apartment N.
We will proceed by filling in the array with the number of people at each position.

    // Example Java code
    int[][] dp = new int[15][15]; // Declare a 15 x 15 array
    for (int i = 0; i < 15; i++) {
        dp[i][1] = 1; // Initialize all apartments on the ground floor
        dp[0][i] = i; // Set the number of people on the ground floor
    }
    
    for (int i = 1; i < 15; i++) {
        for (int j = 2; j < 15; j++) {
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; // Dynamic programming recurrence relation
        }
    }
    

Step 3: Final Calculation

Based on the above rules, we can calculate the value for Kth floor apartment N. For each test case, we simply need to print the value of dp[K][N].

Step 4: Code Implementation

    import java.util.Scanner;

    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int T = sc.nextInt(); // Number of test cases
            int[][] dp = new int[15][15]; // 15x15 array

            // Initialize the DP array
            for (int i = 0; i < 15; i++) {
                dp[i][1] = 1; // Initialize all apartments on the ground floor
                dp[0][i] = i; // Set the number of people on the ground floor
            }

            // Fill the DP table
            for (int i = 1; i < 15; i++) {
                for (int j = 2; j < 15; j++) {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; // Recurrence relation
                }
            }

            // Process each test case
            for (int t = 0; t < T; t++) {
                int K = sc.nextInt(); // Floor number
                int N = sc.nextInt(); // Apartment number
                System.out.println(dp[K][N]); // Print the result
            }

            sc.close();
        }
    }
    

Conclusion

I hope that through this lesson, you have gained a basic understanding of dynamic programming related to solving the “I Will Become the Apartment Manager” problem.
This problem serves as a good example to learn important principles in algorithm design and implementation.
By applying such patterns to various problems, you can solve more complex issues relatively easily.
Practice with more types of problems!

References

Java Coding Test Course, Bellman-Ford

One of the algorithms that frequently appears in coding tests is the Bellman-Ford algorithm. In this article, we will explain the concept of the Bellman-Ford algorithm, how it works, and how to apply it to real problems step by step. We have included detailed solution processes along with various examples to provide useful information for coding tests and job preparation.

Introduction to Bellman-Ford Algorithm

The Bellman-Ford algorithm is used to find the shortest path from a single source to all other vertices in a weighted graph. This algorithm allows for edges with negative weights but cannot provide the shortest path if a negative cycle exists. Therefore, it is essential to check whether a negative cycle is present in the graph before applying the algorithm.

Features of the Bellman-Ford Algorithm

  • When the number of vertices is V, the time complexity is O(VE).
  • The format of edge data can vary.
  • The shortest path can be effectively explored even in graphs without negative weights.
  • It includes built-in functionality for detecting negative cycles.

Problem: Finding the Shortest Path

The following is a problem to find the shortest path using the Bellman-Ford algorithm.

Problem Description

Given a weighted directed graph, write a program to find the shortest path from a specific starting point to all other vertices. The graph may contain negative weights. If a negative cycle exists, the message ‘Negative Cycle’ should be printed.

Input Format

The first line contains the number of vertices V (1 ≤ V ≤ 1000) and the number of edges E (1 ≤ E ≤ 10,000).
The second line contains the starting vertex S (1 ≤ S ≤ V).
The following E lines provide information about each edge in the form of u, v, w (1 ≤ u, v ≤ V, -10^5 ≤ w ≤ 10^5).

Output Format

Print the shortest path lengths to each vertex, separated by spaces.
If there is a negative cycle, print 'Negative Cycle'.

Problem Solution

1. Understanding and Analyzing the Problem

To solve the problem, we first need to understand the graph information provided in the input. We must comprehend the number of vertices and edges and the starting vertex to progress toward calculating the shortest path. This problem requires effectively applying the fundamental structure of the Bellman-Ford algorithm.

2. Algorithm Design

The Bellman-Ford algorithm proceeds through the following steps:

  1. Initialize the shortest path values based on all edges. Set the source to 0 and all other vertices to infinity.
  2. Inspect all edges for V – 1 times and update the shortest path.
  3. Recheck all edges to determine if a negative cycle exists by looking for potential updates in shortest paths.

3. Java Code Implementation

Now, let’s write the Java code based on the algorithm described above.

import java.util.*;

public class BellmanFord {
    static class Edge {
        int u, v, weight;
        Edge(int u, int v, int weight) {
            this.u = u;
            this.v = v;
            this.weight = weight;
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int V = sc.nextInt(); // Number of vertices
        int E = sc.nextInt(); // Number of edges
        int S = sc.nextInt(); // Starting vertex

        List edges = new ArrayList<>();
        for (int i = 0; i < E; i++) {
            int u = sc.nextInt();
            int v = sc.nextInt();
            int weight = sc.nextInt();
            edges.add(new Edge(u, v, weight));
        }

        int[] dist = new int[V + 1];
        Arrays.fill(dist, Integer.MAX_VALUE);
        dist[S] = 0;

        // Execute the algorithm
        for (int i = 1; i <= V - 1; i++) {
            for (Edge edge : edges) {
                if (dist[edge.u] != Integer.MAX_VALUE && 
                    dist[edge.u] + edge.weight < dist[edge.v]) {
                    dist[edge.v] = dist[edge.u] + edge.weight;
                }
            }
        }

        // Detect negative cycles
        for (Edge edge : edges) {
            if (dist[edge.u] != Integer.MAX_VALUE && 
                dist[edge.u] + edge.weight < dist[edge.v]) {
                System.out.println("Negative Cycle");
                return;
            }
        }

        // Output shortest paths
        for (int i = 1; i <= V; i++) {
            if (dist[i] == Integer.MAX_VALUE) {
                System.out.print("Infinity ");
            } else {
                System.out.print(dist[i] + " ");
            }
        }
    }
}

4. Code Explanation

The code above encapsulates the entire flow of the Bellman-Ford algorithm:

  • First, we use the edge list to store all edge data.
  • We declare a distance array (dist) and initialize the distance of the starting point to 0.
  • In the inner loop, we iterate through each edge to update the shortest distance.
  • After reviewing all edges again, we check for the presence of negative cycles.

5. Testing and Validation

After completing the code, it is essential to verify the correct functioning of the algorithm through various test cases. For example:

Input:
5 8
1
1 2 4
1 3 3
2 3 1
3 2 -1
2 4 2
3 4 5
4 5 -3
5 4 2

Output:
0 3 3 5 Infinity 

6. Conclusion

The Bellman-Ford algorithm is a highly useful tool for solving the shortest path problem. Its ability to accommodate negative weights allows it to be applied to various graph problems. Understanding and implementing this algorithm is one of the essential skills for achieving high scores in coding interviews and algorithm exams.

Closing

I hope this course on the Bellman-Ford algorithm has been helpful. I wish it can contribute practically to your coding test preparation. Continue to deepen your learning by applying the algorithm to various problems!