diff --git a/src/main/java/g2601_2700/s2624_snail_traversal/readme.md b/src/main/java/g2601_2700/s2624_snail_traversal/readme.md new file mode 100644 index 000000000..25db07490 --- /dev/null +++ b/src/main/java/g2601_2700/s2624_snail_traversal/readme.md @@ -0,0 +1,44 @@ +2624\. Snail Traversal + +Medium + +Write code that enhances all arrays such that you can call the `snail(rowsCount, colsCount)` method that transforms the 1D array into a 2D array organised in the pattern known as **snail traversal order**. Invalid input values should output an empty array. If `rowsCount * colsCount !== nums.length`, the input is considered invalid. + +**Snail traversal order**starts at the top left cell with the first value of the current array. It then moves through the entire first column from top to bottom, followed by moving to the next column on the right and traversing it from bottom to top. This pattern continues, alternating the direction of traversal with each column, until the entire current array is covered. For example, when given the input array `[19, 10, 3, 7, 9, 8, 5, 2, 1, 17, 16, 14, 12, 18, 6, 13, 11, 20, 4, 15]` with `rowsCount = 5` and `colsCount = 4`, the desired output matrix is shown below. Note that iterating the matrix following the arrows corresponds to the order of numbers in the original array. + +![Traversal Diagram](https://assets.leetcode.com/uploads/2023/04/10/screen-shot-2023-04-10-at-100006-pm.png) + +**Example 1:** + +**Input:** nums = [19, 10, 3, 7, 9, 8, 5, 2, 1, 17, 16, 14, 12, 18, 6, 13, 11, 20, 4, 15] rowsCount = 5 colsCount = 4 + +**Output:** + +[ + [19,17,16,15], + [10,1,14,4], + [3,2,12,20], + [7,5,18,11], + [9,8,6,13] +] + +**Example 2:** + +**Input:** nums = [1,2,3,4] rowsCount = 1 colsCount = 4 + +**Output:** [[1, 2, 3, 4]] + +**Example 3:** + +**Input:** nums = [1,3] rowsCount = 2 colsCount = 2 + +**Output:** [] + +**Explanation:** 2 multiplied by 2 is 4, and the original array [1,3] has a length of 2; therefore, the input is invalid. + +**Constraints:** + +* `0 <= nums.length <= 250` +* `1 <= nums[i] <= 1000` +* `1 <= rowsCount <= 250` +* `1 <= colsCount <= 250` \ No newline at end of file diff --git a/src/main/java/g2601_2700/s2624_snail_traversal/solution.ts b/src/main/java/g2601_2700/s2624_snail_traversal/solution.ts new file mode 100644 index 000000000..fa9303cb7 --- /dev/null +++ b/src/main/java/g2601_2700/s2624_snail_traversal/solution.ts @@ -0,0 +1,27 @@ +// #Medium #2023_08_31_Time_175_ms_(92.96%)_Space_64.2_MB_(32.75%) + +declare global { + interface Array { + snail(rowsCount: number, colsCount: number): number[][] + } +} + +Array.prototype.snail = function (rowsCount: number, colsCount: number): number[][] { //NOSONAR + if (rowsCount * colsCount !== this.length) return [] + let res: number[][] = [] + for (let i = 0; i < this.length; i++) { + let col = Math.floor(i / rowsCount) + let row = i % rowsCount + row = col % 2 === 0 ? row : rowsCount - row - 1 + if (res[row] === undefined) res[row] = [] + res[row].push(this[i]) + } + return res +} + +/* + * const arr = [1,2,3,4]; + * arr.snail(1,4); // [[1,2,3,4]] + */ + +export {} diff --git a/src/main/java/g2601_2700/s2625_flatten_deeply_nested_array/readme.md b/src/main/java/g2601_2700/s2625_flatten_deeply_nested_array/readme.md new file mode 100644 index 000000000..2f27b4151 --- /dev/null +++ b/src/main/java/g2601_2700/s2625_flatten_deeply_nested_array/readme.md @@ -0,0 +1,43 @@ +2625\. Flatten Deeply Nested Array + +Medium + +Given a **multi-dimensional** array `arr` and a depth `n`, return a **flattened** version of that array. + +A **multi-dimensional** array is a recursive data structure that contains integers or other **multi-dimensional** arrays. + +A **flattened** array is a version of that array with some or all of the sub-arrays removed and replaced with the actual elements in that sub-array. This flattening operation should only be done if the current depth of nesting is less than `n`. The depth of the elements in the first array are considered to be `0`. + +Please solve it without the built-in `Array.flat` method. + +**Example 1:** + +**Input** arr = [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]] n = 0 + +**Output:** [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]] + +**Explanation:** Passing a depth of n=0 will always result in the original array. This is because the smallest possible depth of a subarray (0) is not less than n=0. Thus, no subarray should be flattened. + +**Example 2:** + +**Input** arr = [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]] n = 1 + +**Output:** [1, 2, 3, 4, 5, 6, 7, 8, [9, 10, 11], 12, 13, 14, 15] + +**Explanation:** The subarrays starting with 4, 7, and 13 are all flattened. This is because their depth of 0 is less than 1. However [9, 10, 11] remains unflattened because its depth is 1. + +**Example 3:** + +**Input** arr = [[1, 2, 3], [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]] n = 2 + +**Output:** [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + +**Explanation:** The maximum depth of any subarray is 1. Thus, all of them are flattened. + +**Constraints:** + +* 0 <= count of numbers in arr <= 105 +* 0 <= count of subarrays in arr <= 105 +* `maxDepth <= 1000` +* `-1000 <= each number <= 1000` +* `0 <= n <= 1000` \ No newline at end of file diff --git a/src/main/java/g2601_2700/s2625_flatten_deeply_nested_array/solution.ts b/src/main/java/g2601_2700/s2625_flatten_deeply_nested_array/solution.ts new file mode 100644 index 000000000..98aeadee6 --- /dev/null +++ b/src/main/java/g2601_2700/s2625_flatten_deeply_nested_array/solution.ts @@ -0,0 +1,22 @@ +// #Medium #2023_08_31_Time_84_ms_(98.71%)_Space_61.8_MB_(94.52%) + +type MultiDimensionalArray = (number | MultiDimensionalArray)[] + +const flat = (arr: MultiDimensionalArray, depth: number): MultiDimensionalArray => { + const result: MultiDimensionalArray = [] + + const flatten = (nestedArray: MultiDimensionalArray, currentDepth: number) => { + for (const element of nestedArray) { + if (Array.isArray(element) && currentDepth > 0 && currentDepth <= depth) { + flatten(element, currentDepth - 1) + } else { + result.push(element) + } + } + } + + flatten(arr, depth) + return result +} + +export { flat } diff --git a/src/main/java/g2601_2700/s2626_array_reduce_transformation/readme.md b/src/main/java/g2601_2700/s2626_array_reduce_transformation/readme.md new file mode 100644 index 000000000..0bca8bc48 --- /dev/null +++ b/src/main/java/g2601_2700/s2626_array_reduce_transformation/readme.md @@ -0,0 +1,61 @@ +2626\. Array Reduce Transformation + +Easy + +Given an integer array `nums`, a reducer function `fn`, and an initial value `init`, return a **reduced** array. + +A **reduced** array is created by applying the following operation: `val = fn(init, nums[0])`, `val = fn(val, nums[1])`, `val = fn(val, nums[2])`, `...` until every element in the array has been processed. The final value of `val` is returned. + +If the length of the array is 0, it should return `init`. + +Please solve it without using the built-in `Array.reduce` method. + +**Example 1:** + +**Input:** nums = [1,2,3,4] fn = function sum(accum, curr) { return accum + curr; } init = 0 + +**Output:** 10 + +**Explanation:** initially, the value is init=0. + +(0) + nums[0] = 1 + +(1) + nums[1] = 3 + +(3) + nums[2] = 6 + +(6) + nums[3] = 10 + +The final answer is 10. + +**Example 2:** + +**Input:** nums = [1,2,3,4] fn = function sum(accum, curr) { return accum + curr \* curr; } init = 100 + +**Output:** 130 + +**Explanation:** initially, the value is init=100. + +(100) + nums[0]^2 = 101 + +(101) + nums[1]^2 = 105 + +(105) + nums[2]^2 = 114 + +(114) + nums[3]^2 = 130 + +The final answer is 130. + +**Example 3:** + +**Input:** nums = [] fn = function sum(accum, curr) { return 0; } init = 25 + +**Output:** 25 + +**Explanation:** For empty arrays, the answer is always init. + +**Constraints:** + +* `0 <= nums.length <= 1000` +* `0 <= nums[i] <= 1000` +* `0 <= init <= 1000` \ No newline at end of file diff --git a/src/main/java/g2601_2700/s2626_array_reduce_transformation/solution.ts b/src/main/java/g2601_2700/s2626_array_reduce_transformation/solution.ts new file mode 100644 index 000000000..14d4c31f3 --- /dev/null +++ b/src/main/java/g2601_2700/s2626_array_reduce_transformation/solution.ts @@ -0,0 +1,13 @@ +// #Easy #2023_08_31_Time_52_ms_(91.40%)_Space_44.2_MB_(82.03%) + +type Fn = (accum: number, curr: number) => number + +function reduce(nums: number[], fn: Fn, init: number): number { + let accumulator = init + nums.forEach((num) => { + accumulator = fn(accumulator, num) + }) + return accumulator +} + +export { reduce } diff --git a/src/main/java/g2601_2700/s2627_debounce/readme.md b/src/main/java/g2601_2700/s2627_debounce/readme.md new file mode 100644 index 000000000..06ca46af2 --- /dev/null +++ b/src/main/java/g2601_2700/s2627_debounce/readme.md @@ -0,0 +1,78 @@ +2627\. Debounce + +Medium + +Given a function `fn` and a time in milliseconds `t`, return a **debounced** version of that function. + +A **debounced** function is a function whose execution is delayed by `t` milliseconds and whose execution is cancelled if it is called again within that window of time. The debounced function should also receive the passed parameters. + +For example, let's say `t = 50ms`, and the function was called at `30ms`, `60ms`, and `100ms`. The first 2 function calls would be cancelled, and the 3rd function call would be executed at `150ms`. If instead `t = 35ms`, The 1st call would be cancelled, the 2nd would be executed at `95ms`, and the 3rd would be executed at `135ms`. + +![Debounce Schematic](https://assets.leetcode.com/uploads/2023/04/08/screen-shot-2023-04-08-at-11048-pm.png) + +The above diagram shows how debounce will transform events. Each rectangle represents 100ms and the debounce time is 400ms. Each color represents a different set of inputs. + +Please solve it without using lodash's `_.debounce()` function. + +**Example 1:** + +**Input:** t = 50 calls = [ {"t": 50, inputs: [1]}, {"t": 75, inputs: [2]} ] + +**Output:** [{"t": 125, inputs: [2]}] + +**Explanation:** + + let start = Date.now(); + + function log(...inputs) { + console.log([Date.now() - start, inputs ]) + } + const dlog = debounce(log, 50); + setTimeout(() => dlog(1), 50); + setTimeout(() => dlog(2), 75); + +The 1st call is cancelled by the 2nd call because the 2nd call occurred before 100ms + +The 2nd call is delayed by 50ms and executed at 125ms. The inputs were (2). + +**Example 2:** + +**Input:** + + t = 20 + calls = [ + {"t": 50, inputs: [1]}, + {"t": 100, inputs: [2]} + ] + +**Output:** [{"t": 70, inputs: [1]}, {"t": 120, inputs: [2]}] + +**Explanation:** The 1st call is delayed until 70ms. The inputs were (1). The 2nd call is delayed until 120ms. The inputs were (2). + +**Example 3:** + +**Input:** + + t = 150 + calls = [ + {"t": 50, inputs: [1, 2]}, + {"t": 300, inputs: [3, 4]}, + {"t": 300, inputs: [5, 6]} + ] + +**Output:** [{"t": 200, inputs: [1,2]}, {"t": 450, inputs: [5, 6]}] + +**Explanation:** + +The 1st call is delayed by 150ms and ran at 200ms. The inputs were (1, 2). + +The 2nd call is cancelled by the 3rd call + +The 3rd call is delayed by 150ms and ran at 450ms. The inputs were (5, 6). + +**Constraints:** + +* `0 <= t <= 1000` +* `1 <= calls.length <= 10` +* `0 <= calls[i].t <= 1000` +* `0 <= calls[i].inputs.length <= 10` \ No newline at end of file diff --git a/src/main/java/g2601_2700/s2627_debounce/solution.ts b/src/main/java/g2601_2700/s2627_debounce/solution.ts new file mode 100644 index 000000000..f1b723d37 --- /dev/null +++ b/src/main/java/g2601_2700/s2627_debounce/solution.ts @@ -0,0 +1,22 @@ +// #Medium #2023_08_31_Time_50_ms_(98.23%)_Space_42.5_MB_(83.54%) + +type F = (...p: any[]) => any + +function debounce(fn: F, t: number): F { + let ref = null + return function (...args) { + if (ref !== null) { + clearTimeout(ref) + } + ref = setTimeout(() => fn(...args), t) + } +} + +/* + * const log = debounce(console.log, 100); + * log('Hello'); // cancelled + * log('Hello'); // cancelled + * log('Hello'); // Logged at t=100ms + */ + +export { debounce } diff --git a/src/main/java/g2601_2700/s2629_function_composition/readme.md b/src/main/java/g2601_2700/s2629_function_composition/readme.md new file mode 100644 index 000000000..49c8c80aa --- /dev/null +++ b/src/main/java/g2601_2700/s2629_function_composition/readme.md @@ -0,0 +1,59 @@ +2629\. Function Composition + +Easy + +Given an array of functions [f1, f2, f3, ..., fn], return a new function `fn` that is the **function composition** of the array of functions. + +The **function composition** of `[f(x), g(x), h(x)]` is `fn(x) = f(g(h(x)))`. + +The **function composition** of an empty list of functions is the **identity function** `f(x) = x`. + +You may assume each function in the array accepts one integer as input and returns one integer as output. + +**Example 1:** + +**Input:** functions = [x => x + 1, x => x * x, x => 2 * x], x = 4 + +**Output:** 65 + +**Explanation:** + +Evaluating from right to left ... + +Starting with x = 4. + +2 * (4) = 8 + +(8) * (8) = 64 + +(64) + 1 = 65 + +**Example 2:** + +**Input:** functions = [x => 10 * x, x => 10 * x, x => 10 * x], x = 1 + +**Output:** 1000 + +**Explanation:** + +Evaluating from right to left ... + +10 * (1) = 10 + +10 * (10) = 100 + +10 * (100) = 1000 + +**Example 3:** + +**Input:** functions = [], x = 42 + +**Output:** 42 + +**Explanation:** The composition of zero functions is the identity function + +**Constraints:** + +* `-1000 <= x <= 1000` +* `0 <= functions.length <= 1000` +* `all functions accept and return a single integer` \ No newline at end of file diff --git a/src/main/java/g2601_2700/s2629_function_composition/solution.ts b/src/main/java/g2601_2700/s2629_function_composition/solution.ts new file mode 100644 index 000000000..62f6d92f4 --- /dev/null +++ b/src/main/java/g2601_2700/s2629_function_composition/solution.ts @@ -0,0 +1,20 @@ +// #Easy #2023_08_31_Time_58_ms_(95.63%)_Space_45.3_MB_(73.06%) + +type F = (x: number) => number; + +function compose(functions: F[]): F { + return function (x) { + if (functions.length == 0) return x + for (let ind = functions.length - 1; ind >= 0; ind--) { + x = functions[ind](x) + } + return x + } +} + +/* + * const fn = compose([x => x + 1, x => 2 * x]) + * fn(4) // 9 + */ + +export { compose } diff --git a/src/test/java/g2601_2700/s2624_snail_traversal/solution.test.ts b/src/test/java/g2601_2700/s2624_snail_traversal/solution.test.ts new file mode 100644 index 000000000..aed58cef5 --- /dev/null +++ b/src/test/java/g2601_2700/s2624_snail_traversal/solution.test.ts @@ -0,0 +1,27 @@ +// tslint:disable:no-magic-numbers +import 'src/main/java/g2601_2700/s2624_snail_traversal/solution' +import { expect, test } from 'vitest' + +test('snail', () => { + let nums = [19, 10, 3, 7, 9, 8, 5, 2, 1, 17, 16, 14, 12, 18, 6, 13, 11, 20, 4, 15].snail(5,4) + let result = [ + [19,17,16,15], + [10,1,14,4], + [3,2,12,20], + [7,5,18,11], + [9,8,6,13] + ] + expect(nums).toEqual(result) +}) + +test('snail2', () => { + let nums = [1,2,3,4].snail(1,4) + let result = [[1, 2, 3, 4]] + expect(nums).toEqual(result) +}) + +test('snail3', () => { + let nums = [1,3].snail(2,2) + let result = [] + expect(nums).toEqual(result) +}) diff --git a/src/test/java/g2601_2700/s2625_flatten_deeply_nested_array/solution.test.ts b/src/test/java/g2601_2700/s2625_flatten_deeply_nested_array/solution.test.ts new file mode 100644 index 000000000..6582bbb5d --- /dev/null +++ b/src/test/java/g2601_2700/s2625_flatten_deeply_nested_array/solution.test.ts @@ -0,0 +1,24 @@ +// tslint:disable:no-magic-numbers +import { flat } from 'src/main/java/g2601_2700/s2625_flatten_deeply_nested_array/solution' +import { expect, test } from 'vitest' + +test('flat', () => { + let arr = [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]] + let n = 0 + let result = [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]] + expect(flat(arr, n)).toEqual(result) +}) + +test('flat2', () => { + let arr = [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]] + let n = 1 + let result = [1, 2, 3, 4, 5, 6, 7, 8, [9, 10, 11], 12, 13, 14, 15] + expect(flat(arr, n)).toEqual(result) +}) + +test('flat3', () => { + let arr = [[1, 2, 3], [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]] + let n = 2 + let result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + expect(flat(arr, n)).toEqual(result) +}) diff --git a/src/test/java/g2601_2700/s2626_array_reduce_transformation/solution.test.ts b/src/test/java/g2601_2700/s2626_array_reduce_transformation/solution.test.ts new file mode 100644 index 000000000..42928c2c0 --- /dev/null +++ b/src/test/java/g2601_2700/s2626_array_reduce_transformation/solution.test.ts @@ -0,0 +1,24 @@ +// tslint:disable:no-magic-numbers +import { reduce } from 'src/main/java/g2601_2700/s2626_array_reduce_transformation/solution' +import { expect, test } from 'vitest' + +test('reduce', () => { + let nums = [1,2,3,4] + let fn = function sum(accum, curr) { return accum + curr; } + let init = 0 + expect(reduce(nums, fn, init)).toEqual(10) +}) + +test('reduce2', () => { + let nums = [1,2,3,4] + let fn = function sum(accum, curr) { return accum + curr * curr; } + let init = 100 + expect(reduce(nums, fn, init)).toEqual(130) +}) + +test('reduce3', () => { + let nums = [] + let fn = function sum(accum, curr) { return 0; } + let init = 25 + expect(reduce(nums, fn, init)).toEqual(25) +}) diff --git a/src/test/java/g2601_2700/s2627_debounce/solution.test.ts b/src/test/java/g2601_2700/s2627_debounce/solution.test.ts new file mode 100644 index 000000000..acde1b045 --- /dev/null +++ b/src/test/java/g2601_2700/s2627_debounce/solution.test.ts @@ -0,0 +1,14 @@ +// tslint:disable:no-magic-numbers +import { debounce } from 'src/main/java/g2601_2700/s2627_debounce/solution' +import { expect, test } from 'vitest' + +test('debounce', () => { + const log = debounce(console.log, 100) + log('Hello') + // cancelled + log('Hello') + // cancelled + log('Hello') + // Logged at t=100ms + expect(1).toEqual(1) +}) diff --git a/src/test/java/g2601_2700/s2629_function_composition/solution.test.ts b/src/test/java/g2601_2700/s2629_function_composition/solution.test.ts new file mode 100644 index 000000000..2c6773631 --- /dev/null +++ b/src/test/java/g2601_2700/s2629_function_composition/solution.test.ts @@ -0,0 +1,24 @@ +// tslint:disable:no-magic-numbers +import { compose } from 'src/main/java/g2601_2700/s2629_function_composition/solution' +import { expect, test } from 'vitest' + +test('compose', () => { + let functions = [x => x + 1, x => x * x, x => 2 * x] + let x = 4 + const fn = compose(functions) + expect(fn(x)).toEqual(65) +}) + +test('compose2', () => { + let functions = [x => 10 * x, x => 10 * x, x => 10 * x] + let x = 1 + const fn = compose(functions) + expect(fn(x)).toEqual(1000) +}) + +test('compose3', () => { + let functions = [] + let x = 42 + const fn = compose(functions) + expect(fn(x)).toEqual(42) +})