LeetCode 2879 - Display the First Three Rows

The problem requires displaying the first three rows of a given DataFrame named employees. The DataFrame contains four columns: employeeid, name, department, and salary.

LeetCode Problem 2879

Difficulty: 🟢 Easy
Topics:

Solution

Problem Understanding

The problem requires displaying the first three rows of a given DataFrame named employees. The DataFrame contains four columns: employee_id, name, department, and salary. The input represents a table of employee records, and the expected output is a subset of this table containing only the first three rows in their original order.

The problem is simple and straightforward because it does not involve filtering, sorting, or aggregation. The constraints are minimal: the DataFrame will have at least three rows (implied by the problem example), and the columns contain typical data types such as integers for employee_id and salary, and strings for name and department. The edge cases mostly involve DataFrames that have fewer than three rows, in which case the output should simply return all available rows without error. Another potential edge case is when the DataFrame is empty, which should return an empty DataFrame.

Approaches

The brute-force approach is to manually iterate through the DataFrame row by row, counting up to three rows and collecting them into a new DataFrame. While this works, it is unnecessarily verbose and ignores the built-in functionality provided by Pandas for selecting the top rows. The key insight for a more optimal solution is recognizing that Pandas provides the .head() method, which is explicitly designed for this purpose. Using .head(3) allows retrieving the first three rows efficiently without manually looping.

Approach Time Complexity Space Complexity Notes
Brute Force O(n) O(3) Iterate over each row until three are collected
Optimal O(1) O(1) Use Pandas head(3) method which internally handles indexing

Algorithm Walkthrough

  1. Access the DataFrame: Start by referencing the employees DataFrame passed into the function. No copying or transformation is needed at this stage.
  2. Retrieve the first three rows: Call the .head(3) method on the DataFrame. This efficiently selects the first three rows without needing to loop manually or check indices.
  3. Return the result: The .head() method produces a new DataFrame containing only the requested rows. Return this DataFrame directly.

Why it works: Pandas .head(n) guarantees returning the first n rows in their original order. If n exceeds the number of rows in the DataFrame, it simply returns all available rows without error. This ensures correctness in all cases, including small or empty DataFrames.

Python Solution

import pandas as pd

class Solution:
    def displayTopThreeRows(self, employees: pd.DataFrame) -> pd.DataFrame:
        # Use Pandas head() to get the first 3 rows
        return employees.head(3)

In this implementation, the method displayTopThreeRows takes a DataFrame employees as input. The .head(3) method is called to retrieve the first three rows. This implementation directly maps to the algorithm steps: access the DataFrame, select the top three rows, and return the result. There is no need for explicit loops, conditionals, or manual slicing.

Go Solution

package main

import (
    "github.com/kniren/gota/dataframe"
)

func DisplayTopThreeRows(employees dataframe.DataFrame) dataframe.DataFrame {
    // Slice the DataFrame to include only the first 3 rows
    n := 3
    if employees.Nrow() < n {
        n = employees.Nrow()
    }
    return employees.Subset(makeRange(0, n))
}

// Helper function to generate a range of indices
func makeRange(start, end int) []int {
    r := make([]int, end-start)
    for i := range r {
        r[i] = start + i
    }
    return r
}

In Go, the Gota DataFrame library is used. Unlike Pandas, there is no built-in .Head() method, so we slice the DataFrame manually using the Subset method. The helper function makeRange generates the indices from 0 to 3, or fewer if the DataFrame has less than three rows. This handles the same edge cases as the Python version.

Worked Examples

Example 1

Input employees:

employee_id name department salary
3 Bob Operations 48675
90 Alice Sales 11096
9 Tatiana Engineering 33805
60 Annabelle InformationTechnology 37678
49 Jonathan HumanResources 23793
43 Khaled Administration 40454

Step by step:

  1. Access the employees DataFrame.
  2. Call .head(3) (Python) or Subset([0,1,2]) (Go).
  3. Output:
employee_id name department salary
3 Bob Operations 48675
90 Alice Sales 11096
9 Tatiana Engineering 33805

Complexity Analysis

Measure Complexity Explanation
Time O(1) Accessing the first three rows is a constant-time operation in Pandas or via slicing in Gota.
Space O(1) No additional space beyond the new DataFrame of size at most 3 rows is used.

Even though internally Pandas or Gota may create a view or shallow copy, the operation does not scale with n, so it is effectively constant time for our purposes.

Test Cases

import pandas as pd

# Standard case with more than 3 rows
df1 = pd.DataFrame({
    "employee_id": [3, 90, 9, 60, 49, 43],
    "name": ["Bob", "Alice", "Tatiana", "Annabelle", "Jonathan", "Khaled"],
    "department": ["Operations", "Sales", "Engineering", "InformationTechnology", "HumanResources", "Administration"],
    "salary": [48675, 11096, 33805, 37678, 23793, 40454]
})
assert Solution().displayTopThreeRows(df1).shape[0] == 3  # standard case

# Exactly 3 rows
df2 = pd.DataFrame({
    "employee_id": [1,2,3],
    "name": ["A","B","C"],
    "department": ["X","Y","Z"],
    "salary": [1000,2000,3000]
})
assert Solution().displayTopThreeRows(df2).shape[0] == 3  # boundary case

# Less than 3 rows
df3 = pd.DataFrame({
    "employee_id": [5,6],
    "name": ["D","E"],
    "department": ["P","Q"],
    "salary": [5000,6000]
})
assert Solution().displayTopThreeRows(df3).shape[0] == 2  # returns all rows

# Empty DataFrame
df4 = pd.DataFrame(columns=["employee_id","name","department","salary"])
assert Solution().displayTopThreeRows(df4).shape[0] == 0  # empty DataFrame
Test Why
More than 3 rows Validates normal behavior and correct truncation
Exactly 3 rows Checks boundary behavior for exact limit
Less than 3 rows Ensures function does not error and returns all available rows
Empty DataFrame Confirms function handles empty input gracefully

Edge Cases

One important edge case is a DataFrame with fewer than three rows. A naive implementation that assumes at least three rows could throw an index out-of-range error, but using .head(3) or slicing up to the minimum of 3 and the DataFrame length prevents this.

Another edge case is an empty DataFrame. Any loop-based brute-force method must handle the zero-length scenario, whereas .head(3) naturally returns an empty DataFrame, simplifying the logic.

A third edge case involves very large DataFrames. Even though the dataset may contain millions of rows, retrieving only the first three rows is constant-time and does not depend on the total number of rows, ensuring efficiency and scalability.