LeetCode 2885 - Rename Columns

This problem asks us to rename the column names of a Pandas DataFrame according to a fixed mapping. We are given a DataFrame named students with four columns: - id - first - last - age The goal is to return a DataFrame where these columns have been renamed to more descriptive…

LeetCode Problem 2885

Difficulty: 🟢 Easy
Topics:

Solution

Problem Understanding

This problem asks us to rename the column names of a Pandas DataFrame according to a fixed mapping. We are given a DataFrame named students with four columns:

  • id
  • first
  • last
  • age

The goal is to return a DataFrame where these columns have been renamed to more descriptive names:

Original Column New Column
id student_id
first first_name
last last_name
age age_in_years

Importantly, the actual data inside the DataFrame does not change. Only the column labels are modified. Every row and value must remain exactly the same.

The input represents a Pandas DataFrame containing student information. Each row corresponds to a student, and the columns store identifying and descriptive information. The expected output is the same DataFrame structure, but with renamed column headers.

Since this is a Pandas problem from LeetCode, the input is guaranteed to be a valid DataFrame containing the specified columns. There are no large-scale computational constraints because the operation is simply metadata transformation on column names.

An important observation is that we do not need to manually iterate through rows or reconstruct the DataFrame. Pandas already provides a built-in rename() method specifically for renaming columns efficiently.

A naive implementation might unnecessarily copy all rows into a new DataFrame or manually assign each column, but that introduces unnecessary complexity. Since the problem guarantees the required columns exist, we can safely apply a direct column rename mapping.

Potential edge cases include an empty DataFrame with no rows, because renaming columns should still work correctly, and DataFrames with many rows, where we want to avoid unnecessary row-by-row operations. Fortunately, Pandas column renaming works regardless of row count and operates efficiently.

Approaches

Brute Force Approach

A brute force approach would manually construct a new DataFrame by copying every column one by one under the new names.

For example, we could create a new DataFrame and assign:

  • student_id = students["id"]
  • first_name = students["first"]
  • last_name = students["last"]
  • age_in_years = students["age"]

This approach works because each new column explicitly copies the corresponding original column, preserving the data while changing the names.

However, this method is unnecessarily verbose and potentially inefficient because it creates a new DataFrame and copies column references manually. It also becomes harder to maintain if the number of columns grows.

Optimal Approach

The key insight is that Pandas provides a built-in rename() method designed specifically for renaming columns.

We can define a dictionary that maps original column names to their new names and pass it to:

students.rename(columns=mapping)

This approach is clean, concise, and directly expresses the intent of the problem. Since only metadata changes, Pandas efficiently updates the column names without requiring row-by-row processing.

Approach Time Complexity Space Complexity Notes
Brute Force O(n) O(n) Manually reconstructs a new DataFrame by copying columns
Optimal O(1) O(1) Uses Pandas built-in column renaming

The complexity for the optimal approach is effectively constant because the number of columns is fixed at four. More generally, if there were m columns, renaming would take O(m) time.

Algorithm Walkthrough

  1. Create a mapping dictionary that defines how each column should be renamed.

The dictionary pairs original column names with their desired replacements:

{
    "id": "student_id",
    "first": "first_name",
    "last": "last_name",
    "age": "age_in_years"
}

This mapping makes the transformation explicit and easy to understand. 2. Call the Pandas rename() method on the DataFrame.

We pass the mapping dictionary through the columns parameter so Pandas knows which column names should change. 3. Return the renamed DataFrame.

The resulting DataFrame contains exactly the same rows and values, only with updated column labels.

Why it works

The algorithm works because rename(columns=...) performs a deterministic mapping from old column names to new ones. Every specified column is replaced according to the dictionary, while the underlying row data remains untouched. Since the problem guarantees the required columns exist, the renaming operation always produces the correct output.

Python Solution

import pandas as pd

def renameColumns(students: pd.DataFrame) -> pd.DataFrame:
    return students.rename(
        columns={
            "id": "student_id",
            "first": "first_name",
            "last": "last_name",
            "age": "age_in_years",
        }
    )

The implementation is intentionally concise because Pandas already provides a built-in solution for this task.

The function receives the students DataFrame as input. It immediately calls the rename() method and passes a dictionary to the columns parameter. Each key in the dictionary represents an existing column name, and each value represents the replacement name.

After renaming, the updated DataFrame is returned. No row data is modified, and there is no need for iteration or manual copying.

Go Solution

Although this LeetCode problem is designed for Pandas in Python, a conceptual Go implementation using a table-like structure could look like this:

package main

type Student struct {
	StudentID int
	FirstName string
	LastName  string
	AgeInYears int
}

func renameColumns(data []map[string]interface{}) []map[string]interface{} {
	result := make([]map[string]interface{}, 0, len(data))

	for _, row := range data {
		newRow := map[string]interface{}{
			"student_id": row["id"],
			"first_name": row["first"],
			"last_name": row["last"],
			"age_in_years": row["age"],
		}

		result = append(result, newRow)
	}

	return result
}

Go does not have a built-in equivalent to Pandas DataFrames, so this solution uses a slice of maps to simulate tabular data. Instead of renaming metadata directly, we reconstruct rows with new field names.

Unlike Python, Go requires explicit handling of map creation and data copying because there is no native DataFrame abstraction.

Worked Examples

Example 1

Input DataFrame

id first last age
1 Mason King 6
2 Ava Wright 7
3 Taylor Hall 16
4 Georgia Thompson 18
5 Thomas Moore 10

Step 1: Create rename mapping

Original Renamed
id student_id
first first_name
last last_name
age age_in_years

Step 2: Apply rename(columns=...)

Pandas updates only the column labels.

Step 3: Final DataFrame

student_id first_name last_name age_in_years
1 Mason King 6
2 Ava Wright 7
3 Taylor Hall 16
4 Georgia Thompson 18
5 Thomas Moore 10

Notice that none of the actual student data changes. Only the column names are modified.

Complexity Analysis

Measure Complexity Explanation
Time O(1) Only four fixed columns are renamed
Space O(1) No extra data structures proportional to input size are created

More generally, if there were m columns, the renaming operation would take O(m) time because Pandas must process each column name once. Since this problem has exactly four columns, the runtime is effectively constant.

Test Cases

import pandas as pd

def renameColumns(students: pd.DataFrame) -> pd.DataFrame:
    return students.rename(
        columns={
            "id": "student_id",
            "first": "first_name",
            "last": "last_name",
            "age": "age_in_years",
        }
    )

# Example case from problem statement
students = pd.DataFrame({
    "id": [1, 2, 3, 4, 5],
    "first": ["Mason", "Ava", "Taylor", "Georgia", "Thomas"],
    "last": ["King", "Wright", "Hall", "Thompson", "Moore"],
    "age": [6, 7, 16, 18, 10]
})

result = renameColumns(students)

assert list(result.columns) == [
    "student_id",
    "first_name",
    "last_name",
    "age_in_years"
]  # Provided example

# Empty DataFrame
students = pd.DataFrame(columns=["id", "first", "last", "age"])
result = renameColumns(students)

assert list(result.columns) == [
    "student_id",
    "first_name",
    "last_name",
    "age_in_years"
]  # No rows, only columns

# Single row input
students = pd.DataFrame({
    "id": [1],
    "first": ["Alex"],
    "last": ["Smith"],
    "age": [20]
})

result = renameColumns(students)

assert result.iloc[0]["student_id"] == 1  # Single record preserved
assert result.iloc[0]["first_name"] == "Alex"
assert result.iloc[0]["last_name"] == "Smith"
assert result.iloc[0]["age_in_years"] == 20

# Large number of rows
students = pd.DataFrame({
    "id": list(range(1000)),
    "first": ["A"] * 1000,
    "last": ["B"] * 1000,
    "age": [10] * 1000
})

result = renameColumns(students)

assert len(result) == 1000  # Data preserved
assert "student_id" in result.columns  # Rename successful
Test Why
Problem example Verifies the expected transformation
Empty DataFrame Ensures renaming works even without rows
Single row Confirms data preservation for minimal input
Large dataset Validates efficiency and correctness at scale

Edge Cases

Empty DataFrame

One important edge case is an empty DataFrame that contains the required columns but no rows. A naive implementation that assumes rows exist could fail or behave unexpectedly. This implementation handles the case correctly because rename() only changes column metadata and does not depend on row data.

Single Student Record

A DataFrame containing only one student is another useful boundary case. Some implementations may accidentally alter data structure assumptions when the input size is very small. Since rename() operates only on column names, the row data remains completely intact.

Large Number of Rows

A very large DataFrame could expose inefficiencies in implementations that manually rebuild rows or iterate through records. The chosen solution avoids row-level processing entirely and simply updates column labels, making it efficient regardless of dataset size.