From 7260957333e72140a0c43a8dd634155339e7d40a Mon Sep 17 00:00:00 2001 From: Gabb-c Date: Sat, 13 Apr 2024 19:51:53 -0300 Subject: [PATCH] feat(solutions): add leetcode 54 --- src/arrays/1-two-sum/tests/index.bench.ts | 22 +++-- .../tests/index.bench.ts | 15 ++-- .../tests/index.bench.ts | 18 ++-- src/arrays/54-spiral-matrix/README.md | 22 +++++ src/arrays/54-spiral-matrix/index.ts | 51 ++++++++++++ .../54-spiral-matrix/tests/index.bench.ts | 21 +++++ .../54-spiral-matrix/tests/index.spec.ts | 17 ++++ .../54-spiral-matrix/tests/test-data.ts | 83 +++++++++++++++++++ 8 files changed, 226 insertions(+), 23 deletions(-) create mode 100644 src/arrays/54-spiral-matrix/README.md create mode 100644 src/arrays/54-spiral-matrix/index.ts create mode 100644 src/arrays/54-spiral-matrix/tests/index.bench.ts create mode 100644 src/arrays/54-spiral-matrix/tests/index.spec.ts create mode 100644 src/arrays/54-spiral-matrix/tests/test-data.ts diff --git a/src/arrays/1-two-sum/tests/index.bench.ts b/src/arrays/1-two-sum/tests/index.bench.ts index 8dc4352..c45b1be 100644 --- a/src/arrays/1-two-sum/tests/index.bench.ts +++ b/src/arrays/1-two-sum/tests/index.bench.ts @@ -1,15 +1,19 @@ -import { bench, describe, expect } from "vitest"; +import { bench, describe } from "vitest"; +import type { InputTestData } from "@typings/input-data"; import { twoSum } from ".."; -import { TEST_DATA } from "./test-data"; + +const TEST_DATA: InputTestData<{ nums: number[]; target: number }, number[]> = { + input: { nums: [2, 7, 11, 15], target: 9 }, + expected: [0, 1], +}; describe("Two Sum (benchmark)", () => { - for (const { + const { input: { nums, target }, - expected, - } of TEST_DATA) { - bench(`should find the indices of two numbers that add up to ${target}`, () => { - expect(twoSum(nums, target)).toEqual(expected); - }); - } + } = TEST_DATA; + + bench(`should find the indices of two numbers that add up to ${target}`, () => { + twoSum(nums, target); + }); }); diff --git a/src/arrays/121-best-time-to-buy-and-sell-stock/tests/index.bench.ts b/src/arrays/121-best-time-to-buy-and-sell-stock/tests/index.bench.ts index 33470bd..4563f9c 100644 --- a/src/arrays/121-best-time-to-buy-and-sell-stock/tests/index.bench.ts +++ b/src/arrays/121-best-time-to-buy-and-sell-stock/tests/index.bench.ts @@ -1,12 +1,13 @@ -import { bench, describe, expect } from "vitest"; +import { bench, describe } from "vitest"; +import type { InputTestData } from "@typings/input-data"; import { maxProfit } from ".."; -import { TEST_DATA } from "./test-data"; + +const TEST_DATA: InputTestData = { input: [7, 1, 5, 3, 6, 4], expected: 5 }; describe("Best Time to Buy and Sell Stock (benchmark)", () => { - for (const { input, expected } of TEST_DATA) { - bench("should find the maximum profit", () => { - expect(maxProfit(input)).toEqual(expected); - }); - } + const { input } = TEST_DATA; + bench("should find the maximum profit", () => { + maxProfit(input); + }); }); diff --git a/src/arrays/238-product-of-array-except-self/tests/index.bench.ts b/src/arrays/238-product-of-array-except-self/tests/index.bench.ts index 88beb5b..34e27f3 100644 --- a/src/arrays/238-product-of-array-except-self/tests/index.bench.ts +++ b/src/arrays/238-product-of-array-except-self/tests/index.bench.ts @@ -1,12 +1,16 @@ -import { bench, describe, expect } from "vitest"; +import { bench, describe } from "vitest"; +import type { InputTestData } from "@typings/input-data"; import { productExceptSelf } from ".."; -import { TEST_DATA } from "./test-data"; + +const TEST_DATA: InputTestData = { + input: [1, 2, 3, 4], + expected: [24, 12, 8, 6], +}; describe("Product of Array Except Self (benchmark)", () => { - for (const { input, expected } of TEST_DATA) { - bench(`should return the product of array except self for input [${input.join(",")}]`, () => { - expect(productExceptSelf(input)).toEqual(expected); - }); - } + const { input } = TEST_DATA; + bench("should return the product of array except self", () => { + productExceptSelf(input); + }); }); diff --git a/src/arrays/54-spiral-matrix/README.md b/src/arrays/54-spiral-matrix/README.md new file mode 100644 index 0000000..40b0b17 --- /dev/null +++ b/src/arrays/54-spiral-matrix/README.md @@ -0,0 +1,22 @@ +# 51. Spiral Matrix + +Given an `m x n matrix`, return *all elements of the* `matrix` *in spiral order*. + +### Examples + +``` +Input: matrix = [[1,2,3],[4,5,6],[7,8,9]] +Output: [1,2,3,6,9,8,7,4,5] +``` + +``` +Input: matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] +Output: [1,2,3,4,8,12,11,10,9,5,6,7] +``` + +### Constraints + +- m == matrix.length +- n == matrix[i].length +- 1 <= m, n <= 10 +- -100 <= matrix[i][j] <= 100 diff --git a/src/arrays/54-spiral-matrix/index.ts b/src/arrays/54-spiral-matrix/index.ts new file mode 100644 index 0000000..114efa7 --- /dev/null +++ b/src/arrays/54-spiral-matrix/index.ts @@ -0,0 +1,51 @@ +import type { Matrix } from "@typings/matrix"; + +/** + * Returns the elements of the input matrix in spiral order. + * + * @param {Matrix} matrix - The input matrix. + * @returns {number[]} The elements of the matrix in spiral order. + * + * @timeComplexity O(m * n) - Linear time complexity, where m is the number of rows and n is the number of columns in the matrix. + * @spaceComplexity O(1) - Constant space complexity, as the result array is not included in the space analysis. + * + * @description + * This function traverses the input matrix in a spiral order by repeatedly moving through its boundary elements. + * It maintains four boundary variables representing the outermost row and column indices of the matrix. + * It iteratively moves from left to right, top to bottom, right to left, and bottom to top, updating the boundaries + * after each traversal step until all elements have been visited. + */ +export const spiralOrder = (matrix: Matrix): number[] => { + // Initialize the result array + const res: number[] = []; + + // Initialize boundary variables + let left = 0; + let right = matrix[0].length; + let top = 0; + let bottom = matrix.length; + + // Traverse the matrix in a spiral order + while (left < right && top < bottom) { + // Traverse top row + for (let i = left; i < right; i++) res.push(matrix[top][i]); + top++; + + // Traverse right column + for (let i = top; i < bottom; i++) res.push(matrix[i][right - 1]); + right--; + + // Check if there are still elements to traverse + if (!(left < right && top < bottom)) break; + + // Traverse bottom row + for (let i = right - 1; i > left - 1; i--) res.push(matrix[bottom - 1][i]); + bottom--; + + // Traverse left column + for (let i = bottom - 1; i > top - 1; i--) res.push(matrix[i][left]); + left++; + } + + return res; +}; diff --git a/src/arrays/54-spiral-matrix/tests/index.bench.ts b/src/arrays/54-spiral-matrix/tests/index.bench.ts new file mode 100644 index 0000000..f7430d6 --- /dev/null +++ b/src/arrays/54-spiral-matrix/tests/index.bench.ts @@ -0,0 +1,21 @@ +import { bench, describe } from "vitest"; + +import type { InputTestData } from "@typings/input-data"; +import type { Matrix } from "@typings/matrix"; +import { spiralOrder } from ".."; + +const TEST_DATA: InputTestData, number[]> = { + input: [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9], + ], + expected: [1, 2, 3, 6, 9, 8, 7, 4, 5], +}; + +describe("Spiral Matrix (bench)", () => { + const { input } = TEST_DATA; + bench("should return the elements of the matrix in spiral order", () => { + spiralOrder(input); + }); +}); diff --git a/src/arrays/54-spiral-matrix/tests/index.spec.ts b/src/arrays/54-spiral-matrix/tests/index.spec.ts new file mode 100644 index 0000000..9fc3fe1 --- /dev/null +++ b/src/arrays/54-spiral-matrix/tests/index.spec.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from "vitest"; + +import { spiralOrder } from ".."; +import { TEST_DATA } from "./test-data"; + +describe("Spiral Matrix", () => { + for (const { input, expected } of TEST_DATA) { + it("should return the elements of the matrix in spiral order", () => { + // Validate inputs + expect(input).toBeDefined(); + expect(expected).toBeDefined(); + + // Validate output + expect(spiralOrder(input)).toEqual(expected); + }); + } +}); diff --git a/src/arrays/54-spiral-matrix/tests/test-data.ts b/src/arrays/54-spiral-matrix/tests/test-data.ts new file mode 100644 index 0000000..cb0795b --- /dev/null +++ b/src/arrays/54-spiral-matrix/tests/test-data.ts @@ -0,0 +1,83 @@ +import type { InputTestData } from "@typings/input-data"; // Assuming you have a types file +import type { Matrix } from "@typings/matrix"; + +export const TEST_DATA: InputTestData, number[]>[] = [ + { + // Square matrix with increasing numbers in each row + input: [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9], + ], + expected: [1, 2, 3, 6, 9, 8, 7, 4, 5], + }, + { + // Rectangular matrix with increasing numbers in each row + input: [ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12], + ], + expected: [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7], + }, + { + // Single-element matrix + input: [[1]], + expected: [1], + }, + { + // Single-row matrix + input: [[1, 2, 3]], + expected: [1, 2, 3], + }, + { + // Single-column matrix + input: [[1], [2], [3]], + expected: [1, 2, 3], + }, + { + // Square matrix with decreasing numbers in each row + input: [ + [9, 8, 7], + [6, 5, 4], + [3, 2, 1], + ], + expected: [9, 8, 7, 4, 1, 2, 3, 6, 5], + }, + { + // Rectangular matrix with decreasing numbers in each row + input: [ + [12, 11, 10, 9], + [8, 7, 6, 5], + [4, 3, 2, 1], + ], + expected: [12, 11, 10, 9, 5, 1, 2, 3, 4, 8, 7, 6], + }, + { + // Matrix with negative numbers + input: [ + [-1, -2, -3], + [-4, -5, -6], + [-7, -8, -9], + ], + expected: [-1, -2, -3, -6, -9, -8, -7, -4, -5], + }, + { + // Matrix with positive and negative numbers + input: [ + [1, -2, 3], + [-4, 5, -6], + [7, -8, 9], + ], + expected: [1, -2, 3, -6, 9, -8, 7, -4, 5], + }, + { + // Matrix with zeros + input: [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + ], + expected: [0, 0, 0, 0, 0, 0, 0, 0, 0], + }, +];