diff --git a/solution/0700-0799/0723.Candy Crush/README.md b/solution/0700-0799/0723.Candy Crush/README.md index 0f192402f72e8..63e161a4dcfb9 100644 --- a/solution/0700-0799/0723.Candy Crush/README.md +++ b/solution/0700-0799/0723.Candy Crush/README.md @@ -71,7 +71,11 @@ tags: -### 方法一 +### 方法一:模拟 + +我们可以逐行和逐列遍历矩阵,找到连续三个相同的元素,将它们标记为负数。如果成功标记,我们需要将矩阵中的元素下移,直到没有元素可以下移为止。 + +时间复杂度 $O(m^2 \times n^2)$,其中 $m$ 和 $n$ 分别是矩阵的行数和列数。空间复杂度 $O(1)$。 @@ -85,37 +89,33 @@ class Solution: while run: run = False for i in range(m): - for j in range(n - 2): - if ( - board[i][j] != 0 - and abs(board[i][j]) == abs(board[i][j + 1]) - and abs(board[i][j]) == abs(board[i][j + 2]) + for j in range(2, n): + if board[i][j] and abs(board[i][j]) == abs(board[i][j - 1]) == abs( + board[i][j - 2] ): run = True - board[i][j] = board[i][j + 1] = board[i][j + 2] = -abs( + board[i][j] = board[i][j - 1] = board[i][j - 2] = -abs( board[i][j] ) for j in range(n): - for i in range(m - 2): - if ( - board[i][j] != 0 - and abs(board[i][j]) == abs(board[i + 1][j]) - and abs(board[i][j]) == abs(board[i + 2][j]) + for i in range(2, m): + if board[i][j] and abs(board[i][j]) == abs(board[i - 1][j]) == abs( + board[i - 2][j] ): run = True - board[i][j] = board[i + 1][j] = board[i + 2][j] = -abs( + board[i][j] = board[i - 1][j] = board[i - 2][j] = -abs( board[i][j] ) if run: for j in range(n): - curr = m - 1 + k = m - 1 for i in range(m - 1, -1, -1): if board[i][j] > 0: - board[curr][j] = board[i][j] - curr -= 1 - while curr > -1: - board[curr][j] = 0 - curr -= 1 + board[k][j] = board[i][j] + k -= 1 + while k >= 0: + board[k][j] = 0 + k -= 1 return board ``` @@ -126,42 +126,46 @@ class Solution { public int[][] candyCrush(int[][] board) { int m = board.length, n = board[0].length; boolean run = true; + while (run) { run = false; - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n - 2; ++j) { - if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i][j + 1]) - && Math.abs(board[i][j]) == Math.abs(board[i][j + 2])) { + for (int i = 0; i < m; i++) { + for (int j = 2; j < n; j++) { + if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i][j - 1]) + && Math.abs(board[i][j]) == Math.abs(board[i][j - 2])) { run = true; - board[i][j] = board[i][j + 1] = board[i][j + 2] = -Math.abs(board[i][j]); + int val = Math.abs(board[i][j]); + board[i][j] = board[i][j - 1] = board[i][j - 2] = -val; } } } - for (int j = 0; j < n; ++j) { - for (int i = 0; i < m - 2; ++i) { - if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i + 1][j]) - && Math.abs(board[i][j]) == Math.abs(board[i + 2][j])) { + for (int j = 0; j < n; j++) { + for (int i = 2; i < m; i++) { + if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i - 1][j]) + && Math.abs(board[i][j]) == Math.abs(board[i - 2][j])) { run = true; - board[i][j] = board[i + 1][j] = board[i + 2][j] = -Math.abs(board[i][j]); + int val = Math.abs(board[i][j]); + board[i][j] = board[i - 1][j] = board[i - 2][j] = -val; } } } if (run) { - for (int j = 0; j < n; ++j) { - int curr = m - 1; - for (int i = m - 1; i >= 0; --i) { + for (int j = 0; j < n; j++) { + int k = m - 1; + for (int i = m - 1; i >= 0; i--) { if (board[i][j] > 0) { - board[curr][j] = board[i][j]; - --curr; + board[k][j] = board[i][j]; + k--; } } - while (curr > -1) { - board[curr][j] = 0; - --curr; + while (k >= 0) { + board[k][j] = 0; + k--; } } } } + return board; } } @@ -218,52 +222,114 @@ public: ```go func candyCrush(board [][]int) [][]int { - m, n := len(board), len(board[0]) + m := len(board) + n := len(board[0]) run := true + for run { run = false for i := 0; i < m; i++ { - for j := 0; j < n-2; j++ { - if board[i][j] != 0 && abs(board[i][j]) == abs(board[i][j+1]) && abs(board[i][j]) == abs(board[i][j+2]) { + for j := 2; j < n; j++ { + if board[i][j] != 0 && abs(board[i][j]) == abs(board[i][j-1]) && abs(board[i][j]) == abs(board[i][j-2]) { run = true - t := -abs(board[i][j]) - board[i][j], board[i][j+1], board[i][j+2] = t, t, t + val := abs(board[i][j]) + board[i][j] = -val + board[i][j-1] = -val + board[i][j-2] = -val } } } for j := 0; j < n; j++ { - for i := 0; i < m-2; i++ { - if board[i][j] != 0 && abs(board[i][j]) == abs(board[i+1][j]) && abs(board[i][j]) == abs(board[i+2][j]) { + for i := 2; i < m; i++ { + if board[i][j] != 0 && abs(board[i][j]) == abs(board[i-1][j]) && abs(board[i][j]) == abs(board[i-2][j]) { run = true - t := -abs(board[i][j]) - board[i][j], board[i+1][j], board[i+2][j] = t, t, t + val := abs(board[i][j]) + board[i][j] = -val + board[i-1][j] = -val + board[i-2][j] = -val } } } if run { for j := 0; j < n; j++ { - curr := m - 1 + k := m - 1 for i := m - 1; i >= 0; i-- { if board[i][j] > 0 { - board[curr][j] = board[i][j] - curr-- + board[k][j] = board[i][j] + k-- } } - for curr > -1 { - board[curr][j] = 0 - curr-- + for k >= 0 { + board[k][j] = 0 + k-- } } } } + return board } func abs(x int) int { - if x >= 0 { - return x + if x < 0 { + return -x } - return -x + return x +} +``` + +#### TypeScript + +```ts +function candyCrush(board: number[][]): number[][] { + const m = board.length; + const n = board[0].length; + let run = true; + while (run) { + run = false; + for (let i = 0; i < m; i++) { + for (let j = 2; j < n; j++) { + if ( + board[i][j] !== 0 && + Math.abs(board[i][j]) === Math.abs(board[i][j - 1]) && + Math.abs(board[i][j]) === Math.abs(board[i][j - 2]) + ) { + run = true; + const val = Math.abs(board[i][j]); + board[i][j] = board[i][j - 1] = board[i][j - 2] = -val; + } + } + } + for (let j = 0; j < n; j++) { + for (let i = 2; i < m; i++) { + if ( + board[i][j] !== 0 && + Math.abs(board[i][j]) === Math.abs(board[i - 1][j]) && + Math.abs(board[i][j]) === Math.abs(board[i - 2][j]) + ) { + run = true; + const val = Math.abs(board[i][j]); + board[i][j] = board[i - 1][j] = board[i - 2][j] = -val; + } + } + } + if (run) { + for (let j = 0; j < n; j++) { + let k = m - 1; + for (let i = m - 1; i >= 0; i--) { + if (board[i][j] > 0) { + board[k][j] = board[i][j]; + k--; + } + } + while (k >= 0) { + board[k][j] = 0; + k--; + } + } + } + } + return board; } ``` diff --git a/solution/0700-0799/0723.Candy Crush/README_EN.md b/solution/0700-0799/0723.Candy Crush/README_EN.md index ecf1d5548c52a..946223f5170af 100644 --- a/solution/0700-0799/0723.Candy Crush/README_EN.md +++ b/solution/0700-0799/0723.Candy Crush/README_EN.md @@ -65,7 +65,11 @@ tags: -### Solution 1 +### Solution 1: Simulation + +We can traverse the matrix row by row and column by column to find three consecutive identical elements and mark them as negative numbers. If marking is successful, we need to move the elements in the matrix down until no elements can move down. + +The time complexity is $O(m^2 \times n^2)$, where $m$ and $n$ are the number of rows and columns of the matrix, respectively. The space complexity is $O(1)$. @@ -79,37 +83,33 @@ class Solution: while run: run = False for i in range(m): - for j in range(n - 2): - if ( - board[i][j] != 0 - and abs(board[i][j]) == abs(board[i][j + 1]) - and abs(board[i][j]) == abs(board[i][j + 2]) + for j in range(2, n): + if board[i][j] and abs(board[i][j]) == abs(board[i][j - 1]) == abs( + board[i][j - 2] ): run = True - board[i][j] = board[i][j + 1] = board[i][j + 2] = -abs( + board[i][j] = board[i][j - 1] = board[i][j - 2] = -abs( board[i][j] ) for j in range(n): - for i in range(m - 2): - if ( - board[i][j] != 0 - and abs(board[i][j]) == abs(board[i + 1][j]) - and abs(board[i][j]) == abs(board[i + 2][j]) + for i in range(2, m): + if board[i][j] and abs(board[i][j]) == abs(board[i - 1][j]) == abs( + board[i - 2][j] ): run = True - board[i][j] = board[i + 1][j] = board[i + 2][j] = -abs( + board[i][j] = board[i - 1][j] = board[i - 2][j] = -abs( board[i][j] ) if run: for j in range(n): - curr = m - 1 + k = m - 1 for i in range(m - 1, -1, -1): if board[i][j] > 0: - board[curr][j] = board[i][j] - curr -= 1 - while curr > -1: - board[curr][j] = 0 - curr -= 1 + board[k][j] = board[i][j] + k -= 1 + while k >= 0: + board[k][j] = 0 + k -= 1 return board ``` @@ -120,42 +120,46 @@ class Solution { public int[][] candyCrush(int[][] board) { int m = board.length, n = board[0].length; boolean run = true; + while (run) { run = false; - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n - 2; ++j) { - if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i][j + 1]) - && Math.abs(board[i][j]) == Math.abs(board[i][j + 2])) { + for (int i = 0; i < m; i++) { + for (int j = 2; j < n; j++) { + if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i][j - 1]) + && Math.abs(board[i][j]) == Math.abs(board[i][j - 2])) { run = true; - board[i][j] = board[i][j + 1] = board[i][j + 2] = -Math.abs(board[i][j]); + int val = Math.abs(board[i][j]); + board[i][j] = board[i][j - 1] = board[i][j - 2] = -val; } } } - for (int j = 0; j < n; ++j) { - for (int i = 0; i < m - 2; ++i) { - if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i + 1][j]) - && Math.abs(board[i][j]) == Math.abs(board[i + 2][j])) { + for (int j = 0; j < n; j++) { + for (int i = 2; i < m; i++) { + if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i - 1][j]) + && Math.abs(board[i][j]) == Math.abs(board[i - 2][j])) { run = true; - board[i][j] = board[i + 1][j] = board[i + 2][j] = -Math.abs(board[i][j]); + int val = Math.abs(board[i][j]); + board[i][j] = board[i - 1][j] = board[i - 2][j] = -val; } } } if (run) { - for (int j = 0; j < n; ++j) { - int curr = m - 1; - for (int i = m - 1; i >= 0; --i) { + for (int j = 0; j < n; j++) { + int k = m - 1; + for (int i = m - 1; i >= 0; i--) { if (board[i][j] > 0) { - board[curr][j] = board[i][j]; - --curr; + board[k][j] = board[i][j]; + k--; } } - while (curr > -1) { - board[curr][j] = 0; - --curr; + while (k >= 0) { + board[k][j] = 0; + k--; } } } } + return board; } } @@ -212,52 +216,114 @@ public: ```go func candyCrush(board [][]int) [][]int { - m, n := len(board), len(board[0]) + m := len(board) + n := len(board[0]) run := true + for run { run = false for i := 0; i < m; i++ { - for j := 0; j < n-2; j++ { - if board[i][j] != 0 && abs(board[i][j]) == abs(board[i][j+1]) && abs(board[i][j]) == abs(board[i][j+2]) { + for j := 2; j < n; j++ { + if board[i][j] != 0 && abs(board[i][j]) == abs(board[i][j-1]) && abs(board[i][j]) == abs(board[i][j-2]) { run = true - t := -abs(board[i][j]) - board[i][j], board[i][j+1], board[i][j+2] = t, t, t + val := abs(board[i][j]) + board[i][j] = -val + board[i][j-1] = -val + board[i][j-2] = -val } } } for j := 0; j < n; j++ { - for i := 0; i < m-2; i++ { - if board[i][j] != 0 && abs(board[i][j]) == abs(board[i+1][j]) && abs(board[i][j]) == abs(board[i+2][j]) { + for i := 2; i < m; i++ { + if board[i][j] != 0 && abs(board[i][j]) == abs(board[i-1][j]) && abs(board[i][j]) == abs(board[i-2][j]) { run = true - t := -abs(board[i][j]) - board[i][j], board[i+1][j], board[i+2][j] = t, t, t + val := abs(board[i][j]) + board[i][j] = -val + board[i-1][j] = -val + board[i-2][j] = -val } } } if run { for j := 0; j < n; j++ { - curr := m - 1 + k := m - 1 for i := m - 1; i >= 0; i-- { if board[i][j] > 0 { - board[curr][j] = board[i][j] - curr-- + board[k][j] = board[i][j] + k-- } } - for curr > -1 { - board[curr][j] = 0 - curr-- + for k >= 0 { + board[k][j] = 0 + k-- } } } } + return board } func abs(x int) int { - if x >= 0 { - return x + if x < 0 { + return -x } - return -x + return x +} +``` + +#### TypeScript + +```ts +function candyCrush(board: number[][]): number[][] { + const m = board.length; + const n = board[0].length; + let run = true; + while (run) { + run = false; + for (let i = 0; i < m; i++) { + for (let j = 2; j < n; j++) { + if ( + board[i][j] !== 0 && + Math.abs(board[i][j]) === Math.abs(board[i][j - 1]) && + Math.abs(board[i][j]) === Math.abs(board[i][j - 2]) + ) { + run = true; + const val = Math.abs(board[i][j]); + board[i][j] = board[i][j - 1] = board[i][j - 2] = -val; + } + } + } + for (let j = 0; j < n; j++) { + for (let i = 2; i < m; i++) { + if ( + board[i][j] !== 0 && + Math.abs(board[i][j]) === Math.abs(board[i - 1][j]) && + Math.abs(board[i][j]) === Math.abs(board[i - 2][j]) + ) { + run = true; + const val = Math.abs(board[i][j]); + board[i][j] = board[i - 1][j] = board[i - 2][j] = -val; + } + } + } + if (run) { + for (let j = 0; j < n; j++) { + let k = m - 1; + for (let i = m - 1; i >= 0; i--) { + if (board[i][j] > 0) { + board[k][j] = board[i][j]; + k--; + } + } + while (k >= 0) { + board[k][j] = 0; + k--; + } + } + } + } + return board; } ``` diff --git a/solution/0700-0799/0723.Candy Crush/Solution.go b/solution/0700-0799/0723.Candy Crush/Solution.go index 1b38bb2651eba..13a79d4adc701 100644 --- a/solution/0700-0799/0723.Candy Crush/Solution.go +++ b/solution/0700-0799/0723.Candy Crush/Solution.go @@ -1,48 +1,55 @@ func candyCrush(board [][]int) [][]int { - m, n := len(board), len(board[0]) + m := len(board) + n := len(board[0]) run := true + for run { run = false for i := 0; i < m; i++ { - for j := 0; j < n-2; j++ { - if board[i][j] != 0 && abs(board[i][j]) == abs(board[i][j+1]) && abs(board[i][j]) == abs(board[i][j+2]) { + for j := 2; j < n; j++ { + if board[i][j] != 0 && abs(board[i][j]) == abs(board[i][j-1]) && abs(board[i][j]) == abs(board[i][j-2]) { run = true - t := -abs(board[i][j]) - board[i][j], board[i][j+1], board[i][j+2] = t, t, t + val := abs(board[i][j]) + board[i][j] = -val + board[i][j-1] = -val + board[i][j-2] = -val } } } for j := 0; j < n; j++ { - for i := 0; i < m-2; i++ { - if board[i][j] != 0 && abs(board[i][j]) == abs(board[i+1][j]) && abs(board[i][j]) == abs(board[i+2][j]) { + for i := 2; i < m; i++ { + if board[i][j] != 0 && abs(board[i][j]) == abs(board[i-1][j]) && abs(board[i][j]) == abs(board[i-2][j]) { run = true - t := -abs(board[i][j]) - board[i][j], board[i+1][j], board[i+2][j] = t, t, t + val := abs(board[i][j]) + board[i][j] = -val + board[i-1][j] = -val + board[i-2][j] = -val } } } if run { for j := 0; j < n; j++ { - curr := m - 1 + k := m - 1 for i := m - 1; i >= 0; i-- { if board[i][j] > 0 { - board[curr][j] = board[i][j] - curr-- + board[k][j] = board[i][j] + k-- } } - for curr > -1 { - board[curr][j] = 0 - curr-- + for k >= 0 { + board[k][j] = 0 + k-- } } } } + return board } func abs(x int) int { - if x >= 0 { - return x + if x < 0 { + return -x } - return -x + return x } \ No newline at end of file diff --git a/solution/0700-0799/0723.Candy Crush/Solution.java b/solution/0700-0799/0723.Candy Crush/Solution.java index f7348e9821c9f..301297b502f74 100644 --- a/solution/0700-0799/0723.Candy Crush/Solution.java +++ b/solution/0700-0799/0723.Candy Crush/Solution.java @@ -2,42 +2,46 @@ class Solution { public int[][] candyCrush(int[][] board) { int m = board.length, n = board[0].length; boolean run = true; + while (run) { run = false; - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n - 2; ++j) { - if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i][j + 1]) - && Math.abs(board[i][j]) == Math.abs(board[i][j + 2])) { + for (int i = 0; i < m; i++) { + for (int j = 2; j < n; j++) { + if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i][j - 1]) + && Math.abs(board[i][j]) == Math.abs(board[i][j - 2])) { run = true; - board[i][j] = board[i][j + 1] = board[i][j + 2] = -Math.abs(board[i][j]); + int val = Math.abs(board[i][j]); + board[i][j] = board[i][j - 1] = board[i][j - 2] = -val; } } } - for (int j = 0; j < n; ++j) { - for (int i = 0; i < m - 2; ++i) { - if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i + 1][j]) - && Math.abs(board[i][j]) == Math.abs(board[i + 2][j])) { + for (int j = 0; j < n; j++) { + for (int i = 2; i < m; i++) { + if (board[i][j] != 0 && Math.abs(board[i][j]) == Math.abs(board[i - 1][j]) + && Math.abs(board[i][j]) == Math.abs(board[i - 2][j])) { run = true; - board[i][j] = board[i + 1][j] = board[i + 2][j] = -Math.abs(board[i][j]); + int val = Math.abs(board[i][j]); + board[i][j] = board[i - 1][j] = board[i - 2][j] = -val; } } } if (run) { - for (int j = 0; j < n; ++j) { - int curr = m - 1; - for (int i = m - 1; i >= 0; --i) { + for (int j = 0; j < n; j++) { + int k = m - 1; + for (int i = m - 1; i >= 0; i--) { if (board[i][j] > 0) { - board[curr][j] = board[i][j]; - --curr; + board[k][j] = board[i][j]; + k--; } } - while (curr > -1) { - board[curr][j] = 0; - --curr; + while (k >= 0) { + board[k][j] = 0; + k--; } } } } + return board; } } \ No newline at end of file diff --git a/solution/0700-0799/0723.Candy Crush/Solution.py b/solution/0700-0799/0723.Candy Crush/Solution.py index 5264343d7f3d4..9749812515dbe 100644 --- a/solution/0700-0799/0723.Candy Crush/Solution.py +++ b/solution/0700-0799/0723.Candy Crush/Solution.py @@ -5,35 +5,31 @@ def candyCrush(self, board: List[List[int]]) -> List[List[int]]: while run: run = False for i in range(m): - for j in range(n - 2): - if ( - board[i][j] != 0 - and abs(board[i][j]) == abs(board[i][j + 1]) - and abs(board[i][j]) == abs(board[i][j + 2]) + for j in range(2, n): + if board[i][j] and abs(board[i][j]) == abs(board[i][j - 1]) == abs( + board[i][j - 2] ): run = True - board[i][j] = board[i][j + 1] = board[i][j + 2] = -abs( + board[i][j] = board[i][j - 1] = board[i][j - 2] = -abs( board[i][j] ) for j in range(n): - for i in range(m - 2): - if ( - board[i][j] != 0 - and abs(board[i][j]) == abs(board[i + 1][j]) - and abs(board[i][j]) == abs(board[i + 2][j]) + for i in range(2, m): + if board[i][j] and abs(board[i][j]) == abs(board[i - 1][j]) == abs( + board[i - 2][j] ): run = True - board[i][j] = board[i + 1][j] = board[i + 2][j] = -abs( + board[i][j] = board[i - 1][j] = board[i - 2][j] = -abs( board[i][j] ) if run: for j in range(n): - curr = m - 1 + k = m - 1 for i in range(m - 1, -1, -1): if board[i][j] > 0: - board[curr][j] = board[i][j] - curr -= 1 - while curr > -1: - board[curr][j] = 0 - curr -= 1 + board[k][j] = board[i][j] + k -= 1 + while k >= 0: + board[k][j] = 0 + k -= 1 return board diff --git a/solution/0700-0799/0723.Candy Crush/Solution.ts b/solution/0700-0799/0723.Candy Crush/Solution.ts new file mode 100644 index 0000000000000..85328a2e6cd6e --- /dev/null +++ b/solution/0700-0799/0723.Candy Crush/Solution.ts @@ -0,0 +1,50 @@ +function candyCrush(board: number[][]): number[][] { + const m = board.length; + const n = board[0].length; + let run = true; + while (run) { + run = false; + for (let i = 0; i < m; i++) { + for (let j = 2; j < n; j++) { + if ( + board[i][j] !== 0 && + Math.abs(board[i][j]) === Math.abs(board[i][j - 1]) && + Math.abs(board[i][j]) === Math.abs(board[i][j - 2]) + ) { + run = true; + const val = Math.abs(board[i][j]); + board[i][j] = board[i][j - 1] = board[i][j - 2] = -val; + } + } + } + for (let j = 0; j < n; j++) { + for (let i = 2; i < m; i++) { + if ( + board[i][j] !== 0 && + Math.abs(board[i][j]) === Math.abs(board[i - 1][j]) && + Math.abs(board[i][j]) === Math.abs(board[i - 2][j]) + ) { + run = true; + const val = Math.abs(board[i][j]); + board[i][j] = board[i - 1][j] = board[i - 2][j] = -val; + } + } + } + if (run) { + for (let j = 0; j < n; j++) { + let k = m - 1; + for (let i = m - 1; i >= 0; i--) { + if (board[i][j] > 0) { + board[k][j] = board[i][j]; + k--; + } + } + while (k >= 0) { + board[k][j] = 0; + k--; + } + } + } + } + return board; +} diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md index ba89373513f3f..aa6ba42c903f1 100644 --- a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md @@ -304,4 +304,100 @@ function longestSubarray(nums: number[]): number { + + +### 方法三:双指针(优化) + +方法二中,我们每次会循环移动左指针,直到 $cnt \leq 1$。由于题目求的是最长子数组,意味着我们不需要缩小子数组的长度,因此,如果 $\textit{cnt} \gt 1$,我们只移动左指针一次,右指针也继续向右移动。这样可以保证子数组的长度不会减小。 + +最后,我们返回的答案即为 $n - l - 1$,其中 $l$ 为左指针的位置。 + +时间复杂度 $O(n)$,其中 $n$ 为数组 $nums$ 的长度。空间复杂度 $O(1)$。 + + + +#### Python3 + +```python +class Solution: + def longestSubarray(self, nums: List[int]) -> int: + cnt = l = 0 + for x in nums: + cnt += x ^ 1 + if cnt > 1: + cnt -= nums[l] ^ 1 + l += 1 + return len(nums) - l - 1 +``` + +#### Java + +```java +class Solution { + public int longestSubarray(int[] nums) { + int ans = 0, cnt = 0, l = 0; + for (int x : nums) { + cnt += x ^ 1; + if (cnt > 1) { + cnt -= nums[l++] ^ 1; + } + } + return nums.length - l - 1; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int longestSubarray(vector& nums) { + int ans = 0, cnt = 0, l = 0; + for (int x : nums) { + cnt += x ^ 1; + if (cnt > 1) { + cnt -= nums[l++] ^ 1; + } + } + return nums.size() - l - 1; + } +}; +``` + +#### Go + +```go +func longestSubarray(nums []int) (ans int) { + cnt, l := 0, 0 + for _, x := range nums { + cnt += x ^ 1 + if cnt > 1 { + cnt -= nums[l] ^ 1 + l++ + } + } + return len(nums) - l - 1 +} +``` + +#### TypeScript + +```ts +function longestSubarray(nums: number[]): number { + let [cnt, l] = [0, 0]; + for (const x of nums) { + cnt += x ^ 1; + if (cnt > 1) { + cnt -= nums[l++] ^ 1; + } + } + return nums.length - l - 1; +} +``` + + + + + diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README_EN.md b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README_EN.md index dded8ae77ffb1..c539187f88cc9 100644 --- a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README_EN.md +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README_EN.md @@ -303,4 +303,100 @@ function longestSubarray(nums: number[]): number { + + +### Solution 3: Two Pointers (Optimization) + +In Solution 2, we move the left pointer in a loop until $cnt \leq 1$. Since the problem asks for the longest subarray, it means we don't need to reduce the length of the subarray. Therefore, if $\textit{cnt} \gt 1$, we only move the left pointer once, and the right pointer continues to move to the right. This ensures that the length of the subarray does not decrease. + +Finally, the answer we return is $n - l - 1$, where $l$ is the position of the left pointer. + +The time complexity is $O(n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$. + + + +#### Python3 + +```python +class Solution: + def longestSubarray(self, nums: List[int]) -> int: + cnt = l = 0 + for x in nums: + cnt += x ^ 1 + if cnt > 1: + cnt -= nums[l] ^ 1 + l += 1 + return len(nums) - l - 1 +``` + +#### Java + +```java +class Solution { + public int longestSubarray(int[] nums) { + int ans = 0, cnt = 0, l = 0; + for (int x : nums) { + cnt += x ^ 1; + if (cnt > 1) { + cnt -= nums[l++] ^ 1; + } + } + return nums.length - l - 1; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int longestSubarray(vector& nums) { + int ans = 0, cnt = 0, l = 0; + for (int x : nums) { + cnt += x ^ 1; + if (cnt > 1) { + cnt -= nums[l++] ^ 1; + } + } + return nums.size() - l - 1; + } +}; +``` + +#### Go + +```go +func longestSubarray(nums []int) (ans int) { + cnt, l := 0, 0 + for _, x := range nums { + cnt += x ^ 1 + if cnt > 1 { + cnt -= nums[l] ^ 1 + l++ + } + } + return len(nums) - l - 1 +} +``` + +#### TypeScript + +```ts +function longestSubarray(nums: number[]): number { + let [cnt, l] = [0, 0]; + for (const x of nums) { + cnt += x ^ 1; + if (cnt > 1) { + cnt -= nums[l++] ^ 1; + } + } + return nums.length - l - 1; +} +``` + + + + + diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.cpp b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.cpp new file mode 100644 index 0000000000000..782fa4074e10b --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.cpp @@ -0,0 +1,13 @@ +class Solution { +public: + int longestSubarray(vector& nums) { + int ans = 0, cnt = 0, l = 0; + for (int x : nums) { + cnt += x ^ 1; + if (cnt > 1) { + cnt -= nums[l++] ^ 1; + } + } + return nums.size() - l - 1; + } +}; \ No newline at end of file diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.go b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.go new file mode 100644 index 0000000000000..b35f6bbe1ab57 --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.go @@ -0,0 +1,11 @@ +func longestSubarray(nums []int) (ans int) { + cnt, l := 0, 0 + for _, x := range nums { + cnt += x ^ 1 + if cnt > 1 { + cnt -= nums[l] ^ 1 + l++ + } + } + return len(nums) - l - 1 +} \ No newline at end of file diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.java b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.java new file mode 100644 index 0000000000000..939ac9ed5ad9a --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.java @@ -0,0 +1,12 @@ +class Solution { + public int longestSubarray(int[] nums) { + int ans = 0, cnt = 0, l = 0; + for (int x : nums) { + cnt += x ^ 1; + if (cnt > 1) { + cnt -= nums[l++] ^ 1; + } + } + return nums.length - l - 1; + } +} \ No newline at end of file diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.py b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.py new file mode 100644 index 0000000000000..9ecb4561fb35f --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.py @@ -0,0 +1,9 @@ +class Solution: + def longestSubarray(self, nums: List[int]) -> int: + cnt = l = 0 + for x in nums: + cnt += x ^ 1 + if cnt > 1: + cnt -= nums[l] ^ 1 + l += 1 + return len(nums) - l - 1 diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.ts b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.ts new file mode 100644 index 0000000000000..b14d30d363d2e --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution3.ts @@ -0,0 +1,10 @@ +function longestSubarray(nums: number[]): number { + let [cnt, l] = [0, 0]; + for (const x of nums) { + cnt += x ^ 1; + if (cnt > 1) { + cnt -= nums[l++] ^ 1; + } + } + return nums.length - l - 1; +} diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README.md b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README.md index b3ac96e7b9601..ef91e6305feec 100644 --- a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README.md +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README.md @@ -182,4 +182,109 @@ function longestSemiRepetitiveSubstring(s: string): number { + + +### 方法二:双指针(优化) + +由于题目只需要我们找到最长的半重复子字符串的长度,因此,每次当区间内相邻字符相等的个数超过 $1$ 时,我们可以只移动左指针 $l$ 一次,右指针 $r$ 继续向右移动。这样可以保证子字符串的长度不会减小。 + +最后答案为 $n - l$,其中 $n$ 是字符串的长度。 + +时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度 $O(1)$。 + + + +#### Python3 + +```python +class Solution: + def longestSemiRepetitiveSubstring(self, s: str) -> int: + n = len(s) + cnt = l = 0 + for i in range(1, n): + cnt += s[i] == s[i - 1] + if cnt > 1: + cnt -= s[l] == s[l + 1] + l += 1 + return n - l +``` + +#### Java + +```java +class Solution { + public int longestSemiRepetitiveSubstring(String s) { + int n = s.length(); + int cnt = 0, l = 0; + for (int i = 1; i < n; ++i) { + cnt += s.charAt(i) == s.charAt(i - 1) ? 1 : 0; + if (cnt > 1) { + cnt -= s.charAt(l) == s.charAt(++l) ? 1 : 0; + } + } + return n - l; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int longestSemiRepetitiveSubstring(string s) { + int n = s.length(); + int cnt = 0, l = 0; + for (int i = 1; i < n; ++i) { + cnt += s[i] == s[i - 1] ? 1 : 0; + if (cnt > 1) { + cnt -= s[l] == s[++l] ? 1 : 0; + } + } + return n - l; + } +}; +``` + +#### Go + +```go +func longestSemiRepetitiveSubstring(s string) (ans int) { + cnt, l := 0, 0 + for i, c := range s[1:] { + if byte(c) == s[i] { + cnt++ + } + if cnt > 1 { + if s[l] == s[l+1] { + cnt-- + } + l++ + } + } + return len(s) - l +} +``` + +#### TypeScript + +```ts +function longestSemiRepetitiveSubstring(s: string): number { + const n = s.length; + let [cnt, l] = [0, 0]; + for (let i = 1; i < n; ++i) { + cnt += s[i] === s[i - 1] ? 1 : 0; + if (cnt > 1) { + cnt -= s[l] === s[l + 1] ? 1 : 0; + ++l; + } + } + return n - l; +} +``` + + + + + diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README_EN.md b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README_EN.md index da8ad2a201bc1..0374324861d96 100644 --- a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README_EN.md +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README_EN.md @@ -180,4 +180,109 @@ function longestSemiRepetitiveSubstring(s: string): number { + + +### Solution 2: Two Pointers (Optimization) + +Since the problem only requires us to find the length of the longest semi-repetitive substring, each time the number of adjacent identical characters in the interval exceeds $1$, we can move the left pointer $l$ once, while the right pointer $r$ continues to move to the right. This ensures that the length of the substring does not decrease. + +Finally, the answer is $n - l$, where $n$ is the length of the string. + +The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(1)$. + + + +#### Python3 + +```python +class Solution: + def longestSemiRepetitiveSubstring(self, s: str) -> int: + n = len(s) + cnt = l = 0 + for i in range(1, n): + cnt += s[i] == s[i - 1] + if cnt > 1: + cnt -= s[l] == s[l + 1] + l += 1 + return n - l +``` + +#### Java + +```java +class Solution { + public int longestSemiRepetitiveSubstring(String s) { + int n = s.length(); + int cnt = 0, l = 0; + for (int i = 1; i < n; ++i) { + cnt += s.charAt(i) == s.charAt(i - 1) ? 1 : 0; + if (cnt > 1) { + cnt -= s.charAt(l) == s.charAt(++l) ? 1 : 0; + } + } + return n - l; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int longestSemiRepetitiveSubstring(string s) { + int n = s.length(); + int cnt = 0, l = 0; + for (int i = 1; i < n; ++i) { + cnt += s[i] == s[i - 1] ? 1 : 0; + if (cnt > 1) { + cnt -= s[l] == s[++l] ? 1 : 0; + } + } + return n - l; + } +}; +``` + +#### Go + +```go +func longestSemiRepetitiveSubstring(s string) (ans int) { + cnt, l := 0, 0 + for i, c := range s[1:] { + if byte(c) == s[i] { + cnt++ + } + if cnt > 1 { + if s[l] == s[l+1] { + cnt-- + } + l++ + } + } + return len(s) - l +} +``` + +#### TypeScript + +```ts +function longestSemiRepetitiveSubstring(s: string): number { + const n = s.length; + let [cnt, l] = [0, 0]; + for (let i = 1; i < n; ++i) { + cnt += s[i] === s[i - 1] ? 1 : 0; + if (cnt > 1) { + cnt -= s[l] === s[l + 1] ? 1 : 0; + ++l; + } + } + return n - l; +} +``` + + + + + diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.cpp b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.cpp new file mode 100644 index 0000000000000..f5495ccd0a02a --- /dev/null +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.cpp @@ -0,0 +1,14 @@ +class Solution { +public: + int longestSemiRepetitiveSubstring(string s) { + int n = s.length(); + int cnt = 0, l = 0; + for (int i = 1; i < n; ++i) { + cnt += s[i] == s[i - 1] ? 1 : 0; + if (cnt > 1) { + cnt -= s[l] == s[++l] ? 1 : 0; + } + } + return n - l; + } +}; \ No newline at end of file diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.go b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.go new file mode 100644 index 0000000000000..97a8f174e8adb --- /dev/null +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.go @@ -0,0 +1,15 @@ +func longestSemiRepetitiveSubstring(s string) (ans int) { + cnt, l := 0, 0 + for i, c := range s[1:] { + if byte(c) == s[i] { + cnt++ + } + if cnt > 1 { + if s[l] == s[l+1] { + cnt-- + } + l++ + } + } + return len(s) - l +} \ No newline at end of file diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.java b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.java new file mode 100644 index 0000000000000..5d5d1132c3582 --- /dev/null +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.java @@ -0,0 +1,13 @@ +class Solution { + public int longestSemiRepetitiveSubstring(String s) { + int n = s.length(); + int cnt = 0, l = 0; + for (int i = 1; i < n; ++i) { + cnt += s.charAt(i) == s.charAt(i - 1) ? 1 : 0; + if (cnt > 1) { + cnt -= s.charAt(l) == s.charAt(++l) ? 1 : 0; + } + } + return n - l; + } +} \ No newline at end of file diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.py b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.py new file mode 100644 index 0000000000000..b9d9050f85cc4 --- /dev/null +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.py @@ -0,0 +1,10 @@ +class Solution: + def longestSemiRepetitiveSubstring(self, s: str) -> int: + n = len(s) + cnt = l = 0 + for i in range(1, n): + cnt += s[i] == s[i - 1] + if cnt > 1: + cnt -= s[l] == s[l + 1] + l += 1 + return n - l diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.ts b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.ts new file mode 100644 index 0000000000000..0ddf014589585 --- /dev/null +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution2.ts @@ -0,0 +1,12 @@ +function longestSemiRepetitiveSubstring(s: string): number { + const n = s.length; + let [cnt, l] = [0, 0]; + for (let i = 1; i < n; ++i) { + cnt += s[i] === s[i - 1] ? 1 : 0; + if (cnt > 1) { + cnt -= s[l] === s[l + 1] ? 1 : 0; + ++l; + } + } + return n - l; +} diff --git a/solution/3200-3299/3231.Minimum Number of Increasing Subsequence to Be Removed/README.md b/solution/3200-3299/3231.Minimum Number of Increasing Subsequence to Be Removed/README.md index fb6ed09a68c9a..e79f9f6d009f5 100644 --- a/solution/3200-3299/3231.Minimum Number of Increasing Subsequence to Be Removed/README.md +++ b/solution/3200-3299/3231.Minimum Number of Increasing Subsequence to Be Removed/README.md @@ -6,7 +6,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3231.Mi -# [3231. Minimum Number of Increasing Subsequence to Be Removed 🔒](https://leetcode.cn/problems/minimum-number-of-increasing-subsequence-to-be-removed) +# [3231. 要删除的递增子序列的最小数量 🔒](https://leetcode.cn/problems/minimum-number-of-increasing-subsequence-to-be-removed) [English Version](/solution/3200-3299/3231.Minimum%20Number%20of%20Increasing%20Subsequence%20to%20Be%20Removed/README_EN.md) @@ -14,45 +14,47 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3231.Mi -

Given an array of integers nums, you are allowed to perform the following operation any number of times:

+

给定一个整数数组 nums,你可以执行任意次下面的操作:

    -
  • Remove a strictly increasing subsequence from the array.
  • +
  • 从数组删除一个 严格递增子序列
-

Your task is to find the minimum number of operations required to make the array empty.

+

您的任务是找到使数组为 所需的 最小 操作数。

 

-

Example 1:

+ +

示例 1:

-

Input: nums = [5,3,1,4,2]

+

输入:nums = [5,3,1,4,2]

-

Output: 3

+

输出:3

-

Explanation:

+

解释:

-

We remove subsequences [1, 2], [3, 4], [5].

+

我们删除子序列 [1, 2][3, 4][5]

-

Example 2:

+

示例 2:

-

Input: nums = [1,2,3,4,5]

+

输入:nums = [1,2,3,4,5]

-

Output: 1

+

输出:1

-

Example 3:

+

示例 3:

-

Input: nums = [5,4,3,2,1]

+

输入:nums = [5,4,3,2,1]

-

Output: 5

+

输出:5

 

-

Constraints:

+ +

提示:

  • 1 <= nums.length <= 105
  • diff --git a/solution/README.md b/solution/README.md index 2a75156443e7b..7da917ca267d8 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3241,7 +3241,7 @@ | 3228 | [将 1 移动到末尾的最大操作次数](/solution/3200-3299/3228.Maximum%20Number%20of%20Operations%20to%20Move%20Ones%20to%20the%20End/README.md) | `贪心`,`字符串`,`计数` | 中等 | 第 407 场周赛 | | 3229 | [使数组等于目标数组所需的最少操作次数](/solution/3200-3299/3229.Minimum%20Operations%20to%20Make%20Array%20Equal%20to%20Target/README.md) | `栈`,`贪心`,`数组`,`动态规划`,`单调栈` | 困难 | 第 407 场周赛 | | 3230 | [客户购买行为分析](/solution/3200-3299/3230.Customer%20Purchasing%20Behavior%20Analysis/README.md) | `数据库` | 中等 | 🔒 | -| 3231 | [Minimum Number of Increasing Subsequence to Be Removed](/solution/3200-3299/3231.Minimum%20Number%20of%20Increasing%20Subsequence%20to%20Be%20Removed/README.md) | | 困难 | 🔒 | +| 3231 | [要删除的递增子序列的最小数量](/solution/3200-3299/3231.Minimum%20Number%20of%20Increasing%20Subsequence%20to%20Be%20Removed/README.md) | | 困难 | 🔒 | ## 版权