Construct a linked list from 2D matrix
Last Updated :
26 Sep, 2024
Given a Matrix mat of n*n size, the task is to construct a 2D linked list representation of the given matrix.
Example:
Input : mat = [[1 2 3]
[4 5 6]
[7 8 9]]
Output :
Input : mat = [[23 28]
[23 28]]
Output :
[Expected Approach - 1] Recursive Approach - O(n^2) Time and O(n^2) Space
To recursively construct a linked matrix from a 2D matrix, start at the (0, 0) position of the given matrix and create a node for each matrix element. Each node’s right pointer links to the next element in the same row, while its down pointer connects to the element directly below in the column. If the current position is out of bounds, return NULL to end recursive call. This process continues recursively, creating and linking nodes until the entire matrix is transformed into a linked matrix with appropriate horizontal and vertical connections.
Follow the steps below to solve the problem:
- First, create a variable of Node type, which will store the value and the addresses of its right and bottom nodes corresponding to a cell in the matrix.
- Recursively do the following steps for any cell in the matrix:
- If the cell is out of bounds, return null.
- Create a new Node with the value from the matrix for the current cell.
- Recursively construct the right node for the next cell in the row.
- Recursively construct the down node for the next cell in the column.
- Finally return the root Node.
Below is the implementation of the above approach:
C++
// C++ to implement linked matrix
// from a 2D matrix recursively
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *right, *down;
Node(int x) {
data = x;
right = down = nullptr;
}
};
// Function to recursively construct the linked matrix
// from a given 2D vector
Node* constructUtil(vector<vector<int>>& mat,
int i, int j) {
// Base case: if we are out of bounds, return NULL
if (i >= mat.size() || j >= mat[0].size()) {
return nullptr;
}
// Create a new Node with the current matrix value
Node* curr = new Node(mat[i][j]);
// Recursively construct the right and down pointers
curr->right = constructUtil(mat, i, j + 1);
curr->down = constructUtil(mat, i + 1, j);
// Return the constructed Node
return curr;
}
// Function to construct the linked matrix given a 2D vector
Node* constructLinkedMatrix(vector<vector<int>>& mat) {
// Call the utility function starting
// from the top-left corner of the matrix
return constructUtil(mat, 0, 0);
}
void printList(Node *head) {
Node *currRow = head;
while (currRow != nullptr) {
Node *currCol = currRow;
while (currCol != nullptr) {
cout << currCol->data << " ";
currCol = currCol->right;
}
cout << endl;
currRow = currRow->down;
}
}
int main() {
vector<vector<int>> mat = { { 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 } };
Node* head = constructLinkedMatrix(mat);
printList(head);
return 0;
}
Java
// Java to implement linked matrix
// from a 2D matrix recursively
import java.util.ArrayList;
class Node {
int data;
Node right, down;
Node(int data) {
this.data = data;
this.right = null;
this.down = null;
}
}
class GfG {
// Function to recursively construct the linked
// matrix from a given 2D array
static Node constructUtil(int[][] arr, int i, int j) {
// Base case: if we are out of bounds, return null
if (i >= arr.length || j >= arr[0].length) {
return null;
}
// Create a new Node with the current
// matrix value
Node curr = new Node(arr[i][j]);
// Recursively construct the right
// and down pointers
curr.right = constructUtil(arr, i, j + 1);
curr.down = constructUtil(arr, i + 1, j);
// Return the constructed Node
return curr;
}
// Function to construct the linked
// matrix given a 2D array
static Node construct(int arr[][]) {
// Call the utility function starting from the
// top-left corner of the matrix
return constructUtil(arr, 0, 0);
}
static void printList(Node head) {
Node currRow = head;
while (currRow != null) {
Node currCol = currRow;
while (currCol != null) {
System.out.print(currCol.data + " ");
currCol = currCol.right;
}
System.out.println();
currRow = currRow.down;
}
}
public static void main(String[] args) {
int arr[][] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Node head = construct(arr);
printList(head);
}
}
Python
# Python to implement linked matrix
# from a 2D matrix recursively
class Node:
def __init__(self, data):
self.data = data
self.right = None
self.down = None
def constructUtil(mat, i, j):
# Base case: if we are out of bounds, return None
if i >= len(mat) or j >= len(mat[0]):
return None
# Create a new Node with the current matrix value
curr = Node(mat[i][j])
# Recursively construct the right and down pointers
curr.right = constructUtil(mat, i, j + 1)
curr.down = constructUtil(mat, i + 1, j)
# Return the constructed Node
return curr
def constructLinkedMatrix(mat):
# Call the utility function starting
# from the top-left corner of the matrix
return constructUtil(mat, 0, 0)
def printList(head):
currRow = head
while currRow:
currCol = currRow
while currCol:
print(currCol.data, end=" ")
currCol = currCol.right
print()
currRow = currRow.down
if __name__ == "__main__":
mat = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
head = constructLinkedMatrix(mat)
printList(head)
C#
// C# to implement linked matrix
// from a 2D matrix recursively
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node right, down;
public Node(int x) {
data = x;
right = down = null;
}
}
class GfG {
// Recursive utility function to construct
// the linked matrix from a 2D List
static Node ConstructUtil(List<List<int>> arr,
int i, int j) {
// Base case: if we are out of bounds, return null
if (i >= arr.Count || j >= arr[0].Count)
return null;
// Create a new Node with the current list value
Node curr = new Node(arr[i][j]);
// Recursively construct the right and
// down pointers
curr.right = ConstructUtil(arr, i, j + 1);
curr.down = ConstructUtil(arr, i + 1, j);
// Return the constructed Node
return curr;
}
// Function to construct the linked matrix
// from a List of Lists
static Node Construct(List<List<int>> arr) {
// Call the utility function starting
// from the top-left corner
return ConstructUtil(arr, 0, 0);
}
static void PrintList(Node head) {
Node currRow = head;
while (currRow != null) {
Node currCol = currRow;
while (currCol != null) {
Console.Write(currCol.data + " ");
currCol = currCol.right;
}
Console.WriteLine();
currRow = currRow.down;
}
}
static void Main(string[] args) {
List<List<int>> arr = new List<List<int>> {
new List<int> { 1, 2, 3 },
new List<int> { 4, 5, 6 },
new List<int> { 7, 8, 9 }
};
Node head = Construct(arr);
PrintList(head);
}
}
JavaScript
// Javascript to implement linked matrix
// from a 2D matrix recursively
class Node {
constructor(data) {
this.data = data;
this.right = null;
this.down = null;
}
}
// Recursive utility function to construct
// the linked matrix
function constructUtil(arr, i, j) {
// Base case: if out of bounds, return null
if (i >= arr.length || j >= arr[0].length) {
return null;
}
// Create a new Node with the current array value
const curr = new Node(arr[i][j]);
// Recursively construct the right and down pointers
curr.right = constructUtil(arr, i, j + 1);
curr.down = constructUtil(arr, i + 1, j);
// Return the constructed Node
return curr;
}
// Function to construct the linked matrix from a 2D array
function constructLinkedMatrix(arr) {
// Start from the top-left corner
return constructUtil(arr, 0, 0);
}
function printList(head) {
let currRow = head;
while (currRow !== null) {
let currCol = currRow;
while (currCol !== null) {
console.log(currCol.data + " ");
currCol = currCol.right;
}
console.log();
currRow = currRow.down;
}
}
const arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
const head = constructLinkedMatrix(arr);
printList(head);
Time complexity: O(n^2), since each element in the 2D matrix is visited once to create the corresponding node in the linked structure.
Auxiliary space: O(n^2), due to the storage needed for each node in the linked matrix.
[Expected Approach - 2] Iterative Approach - O(n^2) Time and O(n^2) Space
The approach involves creating m linked lists, where m represents the number of rows in a given 2D matrix. Each node in these linked lists stores a reference to its right neighbor. The head pointers of each linked list are maintained in an array. After constructing the linked lists, we traverse through them and for each i-th and (i+1)-th list, we establish the down pointers of each node in i-th list to point to the corresponding node in (i+1)-th list. Please refer to Construct a linked list from 2D matrix (Iterative Approach) for implementation.
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Array Data Structure Guide In this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
4 min read
Sorting Algorithms A Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read