0% found this document useful (0 votes)
2 views22 pages

Ads Notes

The document provides an overview of various array methods in Java, including isEmpty, size, insert, del, indexOf, get, and display, along with their time and space complexities. It also discusses multi-dimensional arrays, mapping techniques for 1D arrays, and matrix operations such as addition, multiplication, and determinant calculation. Additionally, it covers special matrices like diagonal and lower triangular matrices, including their storage and operations.

Uploaded by

ahmadayaan00
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views22 pages

Ads Notes

The document provides an overview of various array methods in Java, including isEmpty, size, insert, del, indexOf, get, and display, along with their time and space complexities. It also discusses multi-dimensional arrays, mapping techniques for 1D arrays, and matrix operations such as addition, multiplication, and determinant calculation. Additionally, it covers special matrices like diagonal and lower triangular matrices, including their storage and operations.

Uploaded by

ahmadayaan00
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Array Methods in Java

1. isEmpty() Method
Explanation
The isEmpty method checks whether an array has any elements.

Java Code

public boolean isEmpty() {


return size == 0;
}

Time Complexity: O(1)


Space Complexity: O(1)

2. size() Method
Explanation
The size method returns the number of elements in the array.

Java Code

public int size() {


return size;
}

Time Complexity: O(1)


Space Complexity: O(1)

3. insert() Method
Explanation
The insert method adds an element at a specified index, shifting the rest.

Java Code
public void insert(int element, int index) {
if (size == arr.length) {
throw new RuntimeException("Array is full");
}
if (index < 0 || index > size) {
throw new RuntimeException("Invalid index");
}
for (int i = size; i > index; i--) {
arr[i] = arr[i - 1];
}
arr[index] = element;
size++;
}

Time Complexity: O(n)

Space Complexity: O(1)

4. del() Method
Explanation
The del method removes an element at a specified index and shifts the elements left.

Java Code

public int del(int index) {


if (size == 0) {
throw new RuntimeException("Array is empty");
}
if (index < 0 || index >= size) {
throw new RuntimeException("Invalid index");
}
int deleted = arr[index];
for (int i = index; i < size - 1; i++) {
arr[i] = arr[i + 1];
}
size--;
return deleted;
}

Time Complexity: O(n)

Space Complexity: O(1)

5. indexOf() Method
Explanation
The indexOf method finds the first occurrence of an element.

Java Code

public int indexOf(int element) {


for (int i = 0; i < size; i++) {
if (arr[i] == element) {
return i;
}
}
return -1;
}

Time Complexity: O(n)

Space Complexity: O(1)

6. get() Method
Explanation
The get method retrieves the element at a specified index.

Java Code

public int get(int index) {


if (index < 0 || index >= size) {
throw new RuntimeException("Invalid index");
}
return arr[index];
}

Time Complexity: O(1)

Space Complexity: O(1)

7. display() Method
Explanation
The display method prints all elements in the array.

Java Code
public void display() {
for (int i = 0; i < size; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}

Time Complexity: O(n)

Space Complexity: O(1)

Exercises
1. Insert elements in an array following a specific
pattern
Explanation
Insert numbers following the sequence 1, 2, 2, 3, 4, 4, 5, etc., with minimal and maximal
movements.

Java Code for Minimum Movements

public void insertSeriesMinMoves(int n) {


for (int i = 1; i <= n; i++) {
insert(i, size);
if (i % 2 == 0) {
insert(i, size);
}
}
}

Time Complexity: O(n)


Space Complexity: O(1)

Java Code for Maximum Movements

public void insertSeriesMaxMoves(int n) {


for (int i = n; i >= 1; i--) {
insert(i, 0);
if (i % 2 == 0) {
insert(i, 0);
}
}
}

Time Complexity: O(n^2)

Space Complexity: O(1)

2. Insert elements based on an index formula


Explanation
Insert elements at index (x + floor(x/2) - 1) for odd x and (x + floor(x/2) - 2) for
even x.

Java Code

public void insertWithFormula(int n) {


for (int i = 1; i <= n; i++) {
int index = (i % 2 == 1) ? (i + i / 2 - 1) : (i + i / 2 - 2);
insert(i, index);
if (i % 2 == 0) {
insert(i, index);
}
}
}

Time Complexity: O(n^2)

Space Complexity: O(1)

3. Remove duplicate elements from an array


Explanation
Delete duplicate elements from a sequence with minimal and maximal movements.

Java Code for Minimum Movements

public void removeDuplicatesMinMoves() {


int i = 0;
while (i < size - 1) {
if (arr[i] == arr[i + 1]) {
del(i + 1);
} else {
i++;
}
}
}

Time Complexity: O(n)

Space Complexity: O(1)


Java Code for Maximum Movements

public void removeDuplicatesMaxMoves() {


for (int i = size - 1; i > 0; i -= 2) {
del(i);
}
}

Time Complexity: O(n^2)


Space Complexity: O(1)

Multi-Dimensional Arrays
In Java, a multi-dimensional array is essentially an array of arrays. For example, a 2D array
represents data in a table-like structure with rows and columns. Each row is itself an array,
making it possible to access elements using two indices.

Example: Creating a 2D Array (3 rows, 2 columns)

// Create a 2D array with 3 rows and 2 columns


int[][] matrix = new int[3][2];

Explanation:

Time Complexity: O(1) for declaration and allocation.


Space Complexity: O(rows * cols) for storing elements.
Java stores 2D arrays in row-major order by default [cite: 67].

Mapping Multi-Dimensional Arrays to 1D Arrays


Storing multi-dimensional arrays as a 1D array can be useful for performance optimizations
or interfacing with lower-level data structures.

2D Arrays
Row Major Order
Elements are stored row by row. For a 2D array with m rows and n columns, the mapping
function is:

public int mapRowMajor(int i, int j, int n) {


return n * i + j;
}

Explanation:

Mapping: The element at row i and column j is placed at index n * i + j in the 1D


array.
Time Complexity: O(1)
Space Complexity: O(1) [cite: 72, 73].

Column Major Order

Elements are stored column by column:

public int mapColumnMajor(int i, int j, int m) {


return m * j + i;
}

Explanation:

Mapping: The element at row i and column j is placed at index m * j + i .


Time Complexity: O(1)
Space Complexity: O(1) [cite: 74, 75].

3D Arrays
For a 3D array with dimensions p x q x r , indices are defined as:

i (0 ≤ i < p)
j (0 ≤ j < q)
k (0 ≤ k < r)

Row Major Order


In row-major order, the array is traversed such that the last index changes fastest, then the
middle, then the first index. The mapping function is:
public int map3DRowMajor(int i, int j, int k, int q, int r) {
return i * (q * r) + j * r + k;
}

Explanation:

Mapping: The element A[i][j][k] is stored at index i*(q*r) + j*r + k in the 1D


array.
Time Complexity: O(1)
Space Complexity: O(1)

Column Major Order


For column-major order (commonly used in languages like Fortran), the first index changes
fastest. The mapping function is:

public int map3DColumnMajor(int i, int j, int k, int p, int q) {


return i + p * j + p * q * k;
}

Explanation:

Mapping: Here, the element A[i][j][k] is stored at index i + p*j + p*q*k .


Time Complexity: O(1)
Space Complexity: O(1)

2D Array Assignment Question


Question:
Suppose you have a 2D array a[m][n] that must be stored in a 1D array in reverse order—
starting from the last row to the first and, within each row, from right to left. Derive the
mapping function for element a[i][j] .

Solution:
To reverse both the row and column orders, replace i with (m - 1 - i) and j with (n -
1 - j) . In standard row-major order, the index is:
normal_index = i * n + j

Thus, the reverse mapping function becomes:

public int mapReverse(int i, int j, int m, int n) {


return (m - 1 - i) * n + (n - 1 - j);
}

Complexity:

Time Complexity: O(1)


Space Complexity: O(1) [cite: 82, 83, 84].

Matrices
A matrix is a rectangular array of numbers arranged in rows and columns. In Java, matrices
are represented using 2D arrays [cite: 87, 88]. Matrices are fundamental in various fields
such as computer graphics, machine learning, and scientific computation.

Matrix Methods
read()
Reads matrix elements from the user.

public void read(int[][] matrix, int rows, int cols) {


Scanner scanner = new Scanner(System.in);
System.out.println("Enter the elements of the matrix:");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = scanner.nextInt();
}
}
}

Complexity:

Time: O(rows * cols)


Space: O(1) [cite: 1256, 1257].

print()
Prints the matrix.

public void print(int[][] matrix, int rows, int cols) {


System.out.println("The matrix is:");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}

Complexity:

Time: O(rows * cols)


Space: O(1).

add(int[][] A, int[][] B)
Adds two matrices element-wise.

public int[][] add(int[][] A, int[][] B, int rows, int cols) {


if (A.length != rows || A[0].length != cols || B.length != rows ||
B[0].length != cols) {
throw new IllegalArgumentException("Matrices must have the same
dimensions for addition.");
}
int[][] result = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result[i][j] = A[i][j] + B[i][j];
}
}
return result;
}

Complexity:

Time: O(rows * cols)


Space: O(rows * cols).

multiply(int[][] A, int[][] B)
Multiplies two matrices.

public int[][] multiply(int[][] A, int[][] B, int rowsA, int colsA, int


colsB) {
if (colsA != B.length) {
throw new IllegalArgumentException("Invalid matrix dimensions for
multiplication.");
}
int[][] result = new int[rowsA][colsB];
for (int i = 0; i < rowsA; i++) {
for (int j = 0; j < colsB; j++) {
for (int k = 0; k < colsA; k++) {
result[i][j] += A[i][k] * B[k][j];
}
}
}
return result;
}

Complexity:

Time: O(rowsA colsA colsB)


Space: O(rowsA * colsB).

det(int[][] matrix, int n)


Calculates the determinant of a square matrix.

public int det(int[][] matrix, int n) {


if (matrix.length != n || matrix[0].length != n) {
throw new IllegalArgumentException("Matrix must be square to
calculate determinant.");
}
// Example: Using Gaussian elimination gives:
// Time Complexity: O(n^3)
// Space Complexity: O(1) if done in place.
}

inverse(int[][] matrix, int n)


Calculates the inverse of a square matrix.

public int[][] inverse(int[][] matrix, int n) {


if (matrix.length != n || matrix[0].length != n) {
throw new IllegalArgumentException("Matrix must be square to
calculate inverse.");
}
// Example: Using Gaussian elimination with an augmented identity
matrix.
// Time Complexity: O(n^3)
// Space Complexity: O(n^2)
}

Special Matrices and Their Operations


Special matrices leverage their inherent structure to optimize storage and operations. Below
are Java class implementations for Diagonal, Lower Triangular, Upper Triangular, and
Tridiagonal matrices.

Diagonal Matrix
Only the diagonal elements are nonzero. We store them in a 1D array.

import java.util.Scanner;

public class DiagonalMatrix {


private int n;
private int[] diag; // Stores only the diagonal elements

public DiagonalMatrix(int n) {
this.n = n;
diag = new int[n];
}

// read(): O(n) time, O(1) extra space


public void read() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter " + n + " diagonal elements:");
for (int i = 0; i < n; i++) {
diag[i] = scanner.nextInt();
}
}

// print(): O(n^2) time, O(1) extra space


public void print() {
System.out.println("Diagonal Matrix:");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print((i == j ? diag[i] : 0) + " ");
}
System.out.println();
}
}

// add(): O(n) time and space


public DiagonalMatrix add(DiagonalMatrix B) {
if (this.n != B.n)
throw new IllegalArgumentException("Dimensions must match.");
DiagonalMatrix result = new DiagonalMatrix(n);
for (int i = 0; i < n; i++) {
result.diag[i] = this.diag[i] + B.diag[i];
}
return result;
}
// multiply(): O(n) time and space (element-wise multiplication)
public DiagonalMatrix multiply(DiagonalMatrix B) {
if (this.n != B.n)
throw new IllegalArgumentException("Dimensions must match.");
DiagonalMatrix result = new DiagonalMatrix(n);
for (int i = 0; i < n; i++) {
result.diag[i] = this.diag[i] * B.diag[i];
}
return result;
}

// det(): O(n) time, O(1) space


public int det() {
int determinant = 1;
for (int i = 0; i < n; i++) {
determinant *= diag[i];
}
return determinant;
}

// inverse(): O(n) time, O(n^2) space (returns full matrix)


// Note: For nonzero diagonal elements only.
public double[][] inverse() {
double[][] inv = new double[n][n];
for (int i = 0; i < n; i++) {
if (diag[i] == 0)
throw new ArithmeticException("Matrix is singular.");
for (int j = 0; j < n; j++) {
inv[i][j] = (i == j) ? 1.0 / diag[i] : 0;
}
}
return inv;
}
}

Lower Triangular Matrix


Only elements on and below the main diagonal are nonzero. They are stored in a 1D array
using the mapping:
index(i, j) = i*(i+1)/2 + j for i ≥ j .

import java.util.Scanner;

public class LowerTriangularMatrix {


private int n;
private int[] elements; // Stores elements of the lower triangle

public LowerTriangularMatrix(int n) {
this.n = n;
elements = new int[n * (n + 1) / 2];
}

// Mapping function: O(1)


private int index(int i, int j) {
if (i < j)
throw new IllegalArgumentException("Invalid indices for lower
triangular matrix.");
return i * (i + 1) / 2 + j;
}

// read(): O(n^2) time (only ~n(n+1)/2 inputs), O(1) extra space


public void read() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the non-zero elements of the lower
triangular matrix:");
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
System.out.print("Element [" + i + "][" + j + "]: ");
elements[index(i, j)] = scanner.nextInt();
}
}
}

// print(): O(n^2) time, O(1) space


public void print() {
System.out.println("Lower Triangular Matrix:");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print((i >= j ? elements[index(i, j)] : 0) + "
");
}
System.out.println();
}
}

// add(): O(n^2) time and space (processing only stored elements)


public LowerTriangularMatrix add(LowerTriangularMatrix B) {
if (this.n != B.n)
throw new IllegalArgumentException("Dimensions must match.");
LowerTriangularMatrix result = new LowerTriangularMatrix(n);
for (int i = 0; i < elements.length; i++) {
result.elements[i] = this.elements[i] + B.elements[i];
}
return result;
}
// multiply(): Optimized using structure; O(n^3) worst-case but fewer
multiplications in practice.
public LowerTriangularMatrix multiply(LowerTriangularMatrix B) {
if (this.n != B.n)
throw new IllegalArgumentException("Dimensions must match.");
LowerTriangularMatrix result = new LowerTriangularMatrix(n);
// For each element in result at (i, j), where i >= j:
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
int sum = 0;
// Only sum from k = j to i (since above-diagonal elements
are zero)
for (int k = j; k <= i; k++) {
sum += this.elements[index(i, k)] *
B.elements[index(k, j)];
}
result.elements[index(i, j)] = sum;
}
}
return result;
}

// det(): O(n) time, O(1) space (product of diagonal elements)


public int det() {
int determinant = 1;
for (int i = 0; i < n; i++) {
determinant *= elements[index(i, i)];
}
return determinant;
}

// inverse(): O(n^2) time, returns full matrix as double[][] using


forward substitution.
public double[][] inverse() {
double[][] inv = new double[n][n];
// Initialize as identity matrix.
for (int i = 0; i < n; i++) {
inv[i][i] = 1.0;
}
// Forward substitution:
for (int i = 0; i < n; i++) {
if (elements[index(i, i)] == 0)
throw new ArithmeticException("Matrix is singular.");
inv[i][i] = 1.0 / elements[index(i, i)];
for (int j = 0; j < i; j++) {
double sum = 0;
for (int k = j; k < i; k++) {
sum += elements[index(i, k)] * inv[k][j];
}
inv[i][j] = -sum / elements[index(i, i)];
}
}
return inv;
}
}

Upper Triangular Matrix


Only elements on and above the main diagonal are nonzero. They are stored in a 1D array
with the mapping for indices (with i ≤ j) as:
index(i, j) = i * n - i*(i-1)/2 + (j - i) .

import java.util.Scanner;

public class UpperTriangularMatrix {


private int n;
private int[] elements; // Stores elements of the upper triangle

public UpperTriangularMatrix(int n) {
this.n = n;
elements = new int[n * (n + 1) / 2];
}

// Mapping function: O(1)


private int index(int i, int j) {
if (i > j)
throw new IllegalArgumentException("Invalid indices for upper
triangular matrix.");
return i * n - i * (i - 1) / 2 + (j - i);
}

// read(): O(n^2) time (only ~n(n+1)/2 inputs), O(1) space


public void read() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the non-zero elements of the upper
triangular matrix:");
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
System.out.print("Element [" + i + "][" + j + "]: ");
elements[index(i, j)] = scanner.nextInt();
}
}
}

// print(): O(n^2) time, O(1) space


public void print() {
System.out.println("Upper Triangular Matrix:");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print((i <= j ? elements[index(i, j)] : 0) + "
");
}
System.out.println();
}
}

// Helper to get element at (i, j)


public int get(int i, int j) {
return (i <= j) ? elements[index(i, j)] : 0;
}

// add(): O(n^2) time and space


public UpperTriangularMatrix add(UpperTriangularMatrix B) {
if (this.n != B.n)
throw new IllegalArgumentException("Dimensions must match.");
UpperTriangularMatrix result = new UpperTriangularMatrix(n);
for (int i = 0; i < elements.length; i++) {
result.elements[i] = this.elements[i] + B.elements[i];
}
return result;
}

// multiply(): Uses structure to reduce operations; worst-case O(n^3)


but optimized in practice.
public UpperTriangularMatrix multiply(UpperTriangularMatrix B) {
if (this.n != B.n)
throw new IllegalArgumentException("Dimensions must match.");
UpperTriangularMatrix result = new UpperTriangularMatrix(n);
// For each (i, j) where i <= j, compute:
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int sum = 0;
for (int k = i; k <= j; k++) {
sum += this.get(i, k) * B.get(k, j);
}
result.elements[index(i, j)] = sum;
}
}
return result;
}

// det(): O(n) time, product of diagonal elements.


public int det() {
int determinant = 1;
for (int i = 0; i < n; i++) {
determinant *= get(i, i);
}
return determinant;
}

// inverse(): O(n^3) worst-case using backward substitution; returns


full matrix.
public double[][] inverse() {
double[][] inv = new double[n][n];
// Initialize identity matrix.
for (int i = 0; i < n; i++) {
inv[i][i] = 1.0;
}
// Backward substitution:
for (int i = n - 1; i >= 0; i--) {
if (get(i, i) == 0)
throw new ArithmeticException("Matrix is singular.");
inv[i][i] = 1.0 / get(i, i);
for (int j = i + 1; j < n; j++) {
double sum = 0;
for (int k = i + 1; k <= j; k++) {
sum += get(i, k) * inv[k][j];
}
inv[i][j] = -sum / get(i, i);
}
}
return inv;
}
}

Tridiagonal Matrix
A tridiagonal matrix has nonzero elements only on the main diagonal and the diagonals
immediately above and below it. We store these in three separate arrays.

import java.util.Scanner;

public class TridiagonalMatrix {


private int n;
private int[] lower; // (n-1) elements: sub-diagonal
private int[] main; // n elements: main diagonal
private int[] upper; // (n-1) elements: super-diagonal

public TridiagonalMatrix(int n) {
this.n = n;
lower = new int[n - 1];
main = new int[n];
upper = new int[n - 1];
}

// read(): O(n) time for each diagonal, overall O(n)


public void read() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the elements of the tridiagonal
matrix:");
// Main diagonal
for (int i = 0; i < n; i++) {
System.out.print("Main diagonal element [" + i + "]: ");
main[i] = scanner.nextInt();
}
// Lower diagonal
for (int i = 0; i < n - 1; i++) {
System.out.print("Lower diagonal element [" + (i + 1) + "][" +
i + "]: ");
lower[i] = scanner.nextInt();
}
// Upper diagonal
for (int i = 0; i < n - 1; i++) {
System.out.print("Upper diagonal element [" + i + "][" + (i +
1) + "]: ");
upper[i] = scanner.nextInt();
}
}

// print(): O(n^2) in full-matrix view, though only 3n-2 elements are


stored.
public void print() {
System.out.println("Tridiagonal Matrix:");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j == i) {
System.out.print(main[i] + " ");
} else if (j == i + 1) {
System.out.print(upper[i] + " ");
} else if (j == i - 1) {
System.out.print(lower[i - 1] + " ");
} else {
System.out.print("0 ");
}
}
System.out.println();
}
}

// add(): O(n) time, processes only stored elements.


public TridiagonalMatrix add(TridiagonalMatrix B) {
if (this.n != B.n)
throw new IllegalArgumentException("Dimensions must match.");
TridiagonalMatrix result = new TridiagonalMatrix(n);
for (int i = 0; i < n; i++) {
result.main[i] = this.main[i] + B.main[i];
}
for (int i = 0; i < n - 1; i++) {
result.lower[i] = this.lower[i] + B.lower[i];
result.upper[i] = this.upper[i] + B.upper[i];
}
return result;
}

// multiply(): Since the product may not be tridiagonal, we convert to


full matrices.
public int[][] multiply(TridiagonalMatrix B) {
if (this.n != B.n)
throw new IllegalArgumentException("Dimensions must match.");
int[][] A_full = this.toFullMatrix();
int[][] B_full = B.toFullMatrix();
int[][] result = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
result[i][j] += A_full[i][k] * B_full[k][j];
}
}
}
return result;
}

// Helper: convert stored representation to full matrix


public int[][] toFullMatrix() {
int[][] full = new int[n][n];
for (int i = 0; i < n; i++) {
full[i][i] = main[i];
if (i < n - 1) {
full[i][i + 1] = upper[i];
full[i + 1][i] = lower[i];
}
}
return full;
}

// det(): O(n) time using recurrence relation


public int det() {
int[] d = new int[n + 1];
d[0] = 1;
d[1] = main[0];
for (int i = 2; i <= n; i++) {
d[i] = main[i - 1] * d[i - 1] - lower[i - 2] * upper[i - 2] *
d[i - 2];
}
return d[n];
}

// inverse(): Uses Gaussian elimination on the full matrix


representation.
// Time Complexity: O(n^3), Space Complexity: O(n^2)
public double[][] inverse() {
int[][] full = this.toFullMatrix();
int N = n;
double[][] inv = new double[N][N];
double[][] aug = new double[N][2 * N];

// Build augmented matrix [full | I]


for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
aug[i][j] = full[i][j];
}
aug[i][N + i] = 1;
}

// Forward elimination with partial pivoting


for (int i = 0; i < N; i++) {
if (aug[i][i] == 0) {
int swapRow = i + 1;
while (swapRow < N && aug[swapRow][i] == 0)
swapRow++;
if (swapRow == N)
throw new ArithmeticException("Matrix is singular.");
double[] temp = aug[i];
aug[i] = aug[swapRow];
aug[swapRow] = temp;
}
double pivot = aug[i][i];
for (int j = 0; j < 2 * N; j++) {
aug[i][j] /= pivot;
}
for (int k = 0; k < N; k++) {
if (k != i) {
double factor = aug[k][i];
for (int j = 0; j < 2 * N; j++) {
aug[k][j] -= factor * aug[i][j];
}
}
}
}

// Extract inverse matrix


for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
inv[i][j] = aug[i][N + j];
}
}
return inv;
}
}

Conclusion
This document now includes:

Mapping Multi-Dimensional Arrays to 1D Arrays:


For 2D arrays using row-major ( index = i * n + j ) and column-major ( index =
m * j + i ) orders.
For 3D arrays using row-major ( index = i * (q * r) + j * r + k ) and column-
major ( index = i + p * j + p * q * k ) orders.
General Matrix Operations: Methods for reading, printing, adding, multiplying,
computing determinants, and finding inverses.
Special Matrices: Complete Java implementations for Diagonal, Lower Triangular,
Upper Triangular, and Tridiagonal matrices with optimized storage and operations.

Each mapping and operation includes an analysis of time (mostly O(1) for index calculations
and up to O(n³) for full matrix operations) and space complexities.

You might also like