From 1d170af464669cbaed3de2758f6122687e5f81e1 Mon Sep 17 00:00:00 2001 From: yennanliu Date: Sun, 22 Dec 2024 17:19:08 +0800 Subject: [PATCH] add 311 java --- README.md | 2 +- data/progress.txt | 2 +- data/to_review.txt | 18 +- .../Array/SparseMatrixMultiplication.java | 162 ++++++++++++++++++ .../src/main/java/dev/workspace6.java | 111 +++++++++--- .../src/main/java/dev/workspace7.java | 106 +++++++++++- 6 files changed, 357 insertions(+), 44 deletions(-) create mode 100644 leetcode_java/src/main/java/LeetCodeJava/Array/SparseMatrixMultiplication.java diff --git a/README.md b/README.md index e49e4536..b52e1897 100644 --- a/README.md +++ b/README.md @@ -240,7 +240,7 @@ 289| [Game of Life](https://leetcode.com/problems/game-of-life/) | [Python](./leetcode_python/Array/game-of-life.py) | _O(m * n)_ | _O(1)_ | Medium |simultaneous,matrix,`complex`, `google`, `amazon`| AGAIN*** (4) 293| [Flip Game](https://leetcode.com/problems/flip-game/) | [Python](./leetcode_python/Array/flip-game.py) | _O(n * (c+1))_ | _O(1)_ | Easy |🔒, `basic`| AGAIN* 308| [Range Sum Query 2D - Mutable](https://leetcode.com/problems/range-sum-query-2d-mutable/) | [Python](./leetcode_python/Array/range-sum-query-2d-mutable.py) | _O(n * (c+1))_ | _O(1)_ | Hard |LC 303, pre-sum, matrix, tree, 🔒, `google`| not start -311| [Sparse Matrix Multiplication](https://leetcode.com/problems/sparse-matrix-multiplication/) | [Python](./leetcode_python/Array/sparse-matrix-multiplication.py) | _O(m * n * l)_ | _O(m * l)_ | Medium |🔒, matrix, `basic`, `fb`| OK**** (4) +311| [Sparse Matrix Multiplication](https://leetcode.com/problems/sparse-matrix-multiplication/) | [Python](./leetcode_python/Array/sparse-matrix-multiplication.py), [Java](./leetcode_java/src/main/java/LeetCodeJava/Array/SparseMatrixMultiplication.java)| _O(m * n * l)_ | _O(m * l)_ | Medium |🔒, matrix, `basic`, `fb`,google| OK**** (5) 334| [Increasing Triplet Subsequence](https://leetcode.com/problems/increasing-triplet-subsequence/) | [Python](./leetcode_python/Array/increasing-triplet-subsequence.py), [Java](./leetcode_java/src/main/java/LeetCodeJava/Array/IncreasingTripletSubsequence.java) | _O(n)_ | _O(1)_ | Medium |AGAIN, check `# 300 Longest Increasing Subsequence`, `trick`, `fb`, google|OK***** (but again) (4) 370| [Range Addition](https://leetcode.com/problems/range-addition/) | [Python](./leetcode_python/Array/range-addition.py), [Java](./leetcode_java/src/main/java/LeetCodeJava/Array/RangeAddition.java) | _O(k + n)_ | _O(1)_ | Medium |prefix, diff array, check `# 598 Range Addition II`, `amazon`, LC 1109, google| AGAIN************** (4) (MUST) 384| [Shuffle an Array](https://leetcode.com/problems/shuffle-an-array/) | [Python](./leetcode_python/Array/shuffle-an-array.py) | _O(n)_ | _O(n)_ | Medium | EPI, `trick` | OK* diff --git a/data/progress.txt b/data/progress.txt index e5df2bdd..6d3b326b 100644 --- a/data/progress.txt +++ b/data/progress.txt @@ -1,4 +1,4 @@ -20241222: 369 +20241222: 369,311 20241221: 370 20241220: 815,871,593,1109 20241214: 560,523 diff --git a/data/to_review.txt b/data/to_review.txt index 745f03d4..3b9b150e 100644 --- a/data/to_review.txt +++ b/data/to_review.txt @@ -1,10 +1,10 @@ -2025-02-15 -> ['369'] +2025-02-15 -> ['369,311'] 2025-02-14 -> ['370'] 2025-02-13 -> ['815,871,593,1109'] 2025-02-07 -> ['560,523'] 2025-02-01 -> ['304,853,325'] 2025-01-26 -> ['370(todo)'] -2025-01-25 -> ['369'] +2025-01-25 -> ['369,311'] 2025-01-24 -> ['370', '34,767'] 2025-01-23 -> ['815,871,593,1109'] 2025-01-20 -> ['722,380'] @@ -13,21 +13,21 @@ 2025-01-16 -> ['776,31'] 2025-01-15 -> ['004(todo),34(todo),162(todo),275(todo)'] 2025-01-14 -> ['986(todo),1229(todo),1868(todo),80(todo),209(todo),283(todo),360(todo),713(todo),532(todo),611(todo)'] -2025-01-12 -> ['369'] +2025-01-12 -> ['369,311'] 2025-01-11 -> ['370', '304,853,325', '394'] 2025-01-10 -> ['815,871,593,1109', '833,950'] 2025-01-05 -> ['370(todo)'] -2025-01-04 -> ['369', '560,523', '53,210,207'] +2025-01-04 -> ['369,311', '560,523', '53,210,207'] 2025-01-03 -> ['370', '34,767', '444'] 2025-01-02 -> ['815,871,593,1109', '1188,130,855(again)'] -2024-12-30 -> ['369', '722,380'] +2024-12-30 -> ['369,311', '722,380'] 2024-12-29 -> ['370', '304,853,325', '33,81'] 2024-12-28 -> ['815,871,593,1109', '900'] -2024-12-27 -> ['369', '560,523', '253', '26,27', '802,1197,26'] +2024-12-27 -> ['369,311', '560,523', '253', '26,27', '802,1197,26'] 2024-12-26 -> ['370', '776,31'] -2024-12-25 -> ['369', '815,871,593,1109', '004(todo),34(todo),162(todo),275(todo)'] -2024-12-24 -> ['369', '370', '986(todo),1229(todo),1868(todo),80(todo),209(todo),283(todo),360(todo),713(todo),532(todo),611(todo)'] -2024-12-23 -> ['369', '370', '815,871,593,1109', '370(todo)'] +2024-12-25 -> ['369,311', '815,871,593,1109', '004(todo),34(todo),162(todo),275(todo)'] +2024-12-24 -> ['369,311', '370', '986(todo),1229(todo),1868(todo),80(todo),209(todo),283(todo),360(todo),713(todo),532(todo),611(todo)'] +2024-12-23 -> ['369,311', '370', '815,871,593,1109', '370(todo)'] 2024-12-22 -> ['370', '815,871,593,1109', '560,523'] 2024-12-21 -> ['815,871,593,1109', '304,853,325', '34,767', '394', '855,846'] 2024-12-20 -> ['833,950', '932'] diff --git a/leetcode_java/src/main/java/LeetCodeJava/Array/SparseMatrixMultiplication.java b/leetcode_java/src/main/java/LeetCodeJava/Array/SparseMatrixMultiplication.java new file mode 100644 index 00000000..80039e14 --- /dev/null +++ b/leetcode_java/src/main/java/LeetCodeJava/Array/SparseMatrixMultiplication.java @@ -0,0 +1,162 @@ +package LeetCodeJava.Array; + +// https://leetcode.com/problems/sparse-matrix-multiplication/description/ +// https://leetcode.ca/all/311.html + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * 311. Sparse Matrix Multiplication + * Given two sparse matrices A and B, return the result of AB. + * + * You may assume that A's column number is equal to B's row number. + * + * Example: + * + * Input: + * + * A = [ + * [ 1, 0, 0], + * [-1, 0, 3] + * ] + * + * B = [ + * [ 7, 0, 0 ], + * [ 0, 0, 0 ], + * [ 0, 0, 1 ] + * ] + * + * Output: + * + * | 1 0 0 | | 7 0 0 | | 7 0 0 | + * AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 | + * | 0 0 1 | + * Difficulty: + * Medium + * Lock: + * Prime + * Company: + * Amazon Apple Bloomberg Facebook Goldman Sachs Google LinkedIn Microsoft Snapchat + * + */ +public class SparseMatrixMultiplication { + + // V0 + // IDEA : ARRAY OP (fix by gpt) + /** + * Why there is 3 loop ? + * + * -> Matrix Multiplication: Ci,j = Sigma(Aik * Bkj) + * + * -> so we have 3 layer loop as below: + * - i : Iterates over the rows of A (outer loop). + * - j : Iterates over the columns of B (second loop). + * - k : Iterates over the “shared dimension” (columns of A or rows of B ) to compute the dot product (inner loop). + * + * + * -> + * + * The Role of the Loops + * 1. Outer loop ( i ): Iterates over the rows of mat1 to calculate each row of the result matrix. + * 2. Middle loop ( j ): Iterates over the columns of mat2 to compute each element in a row of the result matrix. + * 3. Inner loop ( k ): Iterates over the “shared dimension” to compute the dot product of the i^{th} row of mat1 and the j^{th} column of mat2. + * + * + * -> Why the Inner Loop ( k ) Exists ? + * + * -> The inner loop is necessary + * because each element of the result matrix + * is computed as the dot product of a + * row from mat1 and a column from mat2. + * Without this loop, the computation of the dot product would be incomplete. + */ + public static int[][] multiply(int[][] mat1, int[][] mat2) { + // Edge case: Single element matrices + if (mat1.length == 1 && mat1[0].length == 1 && mat2.length == 1 && mat2[0].length == 1) { + return new int[][]{{mat1[0][0] * mat2[0][0]}}; + } + + int l_1 = mat1.length; // Number of rows in mat1 + int w_1 = mat1[0].length; // Number of columns in mat1 (and rows in mat2) + + int w_2 = mat2[0].length; // Number of columns in mat2 + + // Initialize the result matrix + int[][] res = new int[l_1][w_2]; + + // Perform matrix multiplication + for (int i = 0; i < l_1; i++) { + for (int j = 0; j < w_2; j++) { + int sum = 0; // Sum for res[i][j] + for (int k = 0; k < w_1; k++) { + sum += mat1[i][k] * mat2[k][j]; + } + res[i][j] = sum; + } + } + + return res; + } + + // V1 + // IDEA : ARRAY OP (gpt) + public int[][] multiply_1(int[][] A, int[][] B) { + int m = A.length; // Number of rows in A + int n = A[0].length; // Number of columns in A + int p = B[0].length; // Number of columns in B + + int[][] result = new int[m][p]; + + // Iterate through rows of A + for (int i = 0; i < m; i++) { + for (int k = 0; k < n; k++) { + if (A[i][k] != 0) { // Skip zero entries in A + for (int j = 0; j < p; j++) { + if (B[k][j] != 0) { // Skip zero entries in B + result[i][j] += A[i][k] * B[k][j]; + } + } + } + } + } + + return result; + } + + // V2 + // https://leetcode.ca/2016-10-06-311-Sparse-Matrix-Multiplication/ + public int[][] multiply_2(int[][] mat1, int[][] mat2) { + int m = mat1.length, n = mat2[0].length; + int[][] ans = new int[m][n]; + List[] g1 = f(mat1); + List[] g2 = f(mat2); + for (int i = 0; i < m; ++i) { + for (int[] p : g1[i]) { + int k = p[0], x = p[1]; + for (int[] q : g2[k]) { + int j = q[0], y = q[1]; + ans[i][j] += x * y; + } + } + } + return ans; + } + + private List[] f(int[][] mat) { + int m = mat.length, n = mat[0].length; + List[] g = new List[m]; + Arrays.setAll(g, i -> new ArrayList<>()); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (mat[i][j] != 0) { + g[i].add(new int[] {j, mat[i][j]}); + } + } + } + return g; + } + + // V3 +} diff --git a/leetcode_java/src/main/java/dev/workspace6.java b/leetcode_java/src/main/java/dev/workspace6.java index 00068c96..c8ec9c0d 100644 --- a/leetcode_java/src/main/java/dev/workspace6.java +++ b/leetcode_java/src/main/java/dev/workspace6.java @@ -515,32 +515,89 @@ public ListNode plusOne(ListNode head) { return null; } - // v1 -// public ListNode plusOne_1(ListNode head) { -// if (head == null){ -// return new ListNode(1); // ?? -// } -// List list = new ArrayList<>(); -// while(head != null){ -// list.add(head.val); -// head = head.next; -// } -// // ??? -// int cur = 0; -// for (int j = list.size(); j >= 0; j--){ -// cur += (10 ^ j) * list.get(j); -// } -// cur += 1; -// ListNode res = new ListNode(); -// String string = String.valueOf(cur); -// for (String x : string.split("")){ -// ListNode tmp = new ListNode(); -// tmp.val = Integer.parseInt(x); -// res.next = tmp; -// res = res.next; -// } -// -// return res; -// } + // v1 + // public ListNode plusOne_1(ListNode head) { + // if (head == null){ + // return new ListNode(1); // ?? + // } + // List list = new ArrayList<>(); + // while(head != null){ + // list.add(head.val); + // head = head.next; + // } + // // ??? + // int cur = 0; + // for (int j = list.size(); j >= 0; j--){ + // cur += (10 ^ j) * list.get(j); + // } + // cur += 1; + // ListNode res = new ListNode(); + // String string = String.valueOf(cur); + // for (String x : string.split("")){ + // ListNode tmp = new ListNode(); + // tmp.val = Integer.parseInt(x); + // res.next = tmp; + // res = res.next; + // } + // + // return res; + // } + + // LC 311 + // https://leetcode.ca/2016-10-06-311-Sparse-Matrix-Multiplication/ + // 4.39 - 4.50 pm + /** + * IDEA 1: ARRAY OP (brute force) + * + * Input: + * + * A = [ + * [ 1, 0, 0], + * [-1, 0, 3] + * ] + * + * B = [ + * [ 7, 0, 0 ], + * [ 0, 0, 0 ], + * [ 0, 0, 1 ] + * ] + * + * Output: + * + * | 1 0 0 | | 7 0 0 | | 7 0 0 | + * AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 | + * | 0 0 1 | + * + */ + public int[][] multiply(int[][] mat1, int[][] mat2) { + + // edge case + if (mat1.length == 1 && mat1[0].length == 1 && mat2.length == 1 && mat2[0].length == 1){ + int[][] res = new int[][]{}; + res[0][0] = mat1[0][0] * mat2[0][0]; + return res; + } + + int l_1 = mat1.length; + int w_1 = mat1[0].length; + + int l_2 = mat2.length; + int w_2 = mat2[0].length; + + int[][] res = new int[l_1][w_2]; // ??? + + for(int i = 0; i < l_1; i++){ + int tmp = 0; + for (int j = 0; j < w_2; j++){ + System.out.println(">>> i = " + i + ", j = " + j + ", tmp = " + tmp); + tmp += (mat1[i][j] * mat2[j][i]); + res[i][j] = tmp; + } + //res[i][j] = tmp; // ? + } + + return res; + } + } diff --git a/leetcode_java/src/main/java/dev/workspace7.java b/leetcode_java/src/main/java/dev/workspace7.java index 59bb5166..29c4dd32 100644 --- a/leetcode_java/src/main/java/dev/workspace7.java +++ b/leetcode_java/src/main/java/dev/workspace7.java @@ -5,16 +5,110 @@ public class workspace7 { public static void main(String[] args) { - int len = 5; - int[][] updates ={ {1,3,2}, {2,4,3}, {0,2,-2} }; - int[] res = getModifiedArray(len, updates); + // ------------------- TEST 1 +// int len = 5; +// int[][] updates ={ {1,3,2}, {2,4,3}, {0,2,-2} }; +// int[] res = getModifiedArray(len, updates); +// System.out.println(">>> res = "); +// for (int x : res){ +// // [-2,0,3,5,3] +// System.out.println(x); +// } + + // ------------------- TEST 2 + int[][] mat1 = new int[][]{ {1,0,0}, {-1,0,3} }; + int[][] mat2 = new int[][]{ {7,0,0}, {0,0,0}, {0,0,1} }; + int[][] res = multiply(mat1, mat2); System.out.println(">>> res = "); - for (int x : res){ - // [-2,0,3,5,3] - System.out.println(x); + for (int i = 0; i < res.length; i++){ + for (int j = 0; j < res[0].length; j++){ + System.out.println(res[i][j]); + } } } + + public static int[][] multiply(int[][] mat1, int[][] mat2) { + // Edge case: Single element matrices + if (mat1.length == 1 && mat1[0].length == 1 && mat2.length == 1 && mat2[0].length == 1) { + return new int[][]{{mat1[0][0] * mat2[0][0]}}; + } + + int l_1 = mat1.length; // Number of rows in mat1 + int w_1 = mat1[0].length; // Number of columns in mat1 (and rows in mat2) + + int w_2 = mat2[0].length; // Number of columns in mat2 + + // Initialize the result matrix + int[][] res = new int[l_1][w_2]; + + // Perform matrix multiplication + for (int i = 0; i < l_1; i++) { + for (int j = 0; j < w_2; j++) { + int sum = 0; // Sum for res[i][j] + for (int k = 0; k < w_1; k++) { + sum += mat1[i][k] * mat2[k][j]; + } + res[i][j] = sum; + } + } + + return res; + } + +// public static int[][] multiply(int[][] A, int[][] B) { +// int m = A.length; // Number of rows in A +// int n = A[0].length; // Number of columns in A +// int p = B[0].length; // Number of columns in B +// +// int[][] result = new int[m][p]; +// +// // Iterate through rows of A +// for (int i = 0; i < m; i++) { +// for (int k = 0; k < n; k++) { +// if (A[i][k] != 0) { // Skip zero entries in A +// for (int j = 0; j < p; j++) { +// if (B[k][j] != 0) { // Skip zero entries in B +// result[i][j] += A[i][k] * B[k][j]; +// } +// } +// } +// } +// } +// +// return result; +// } + +// public static int[][] multiply(int[][] mat1, int[][] mat2) { +// +// // edge case +// if (mat1.length == 1 && mat1[0].length == 1 && mat2.length == 1 && mat2[0].length == 1){ +// int[][] res = new int[][]{}; +// res[0][0] = mat1[0][0] * mat2[0][0]; +// return res; +// } +// +// int l_1 = mat1.length; +// int w_1 = mat1[0].length; +// +// int l_2 = mat2.length; +// int w_2 = mat2[0].length; +// +// int[][] res = new int[l_1][w_2]; // ??? +// +// for(int i = 0; i < l_1; i++){ +// int tmp = 0; +// for (int j = 0; j < w_2; j++){ +// System.out.println(">>> i = " + i + ", j = " + j + ", tmp = " + tmp); +// tmp += (mat1[i][j] * mat2[j][i]); +// res[i][j] = tmp; +// } +// //res[i][j] = tmp; // ? +// } +// +// return res; +// } + public static int[] getModifiedArray(int length, int[][] updates) { int[] tmp = new int[length+1]; // ?