diff --git a/solution/0300-0399/0375.Guess Number Higher or Lower II/README.md b/solution/0300-0399/0375.Guess Number Higher or Lower II/README.md index 2188a0a1c5f4d..0aab302480185 100644 --- a/solution/0300-0399/0375.Guess Number Higher or Lower II/README.md +++ b/solution/0300-0399/0375.Guess Number Higher or Lower II/README.md @@ -90,7 +90,13 @@ tags: -### 方法一 +### 方法一:动态规划 + +我们定义 $f[i][j]$ 表示在区间 $[i, j]$ 中猜中任意一个数最少需要花费的钱数。初始时 $f[i][i] = 0$,因为猜中了唯一的数不需要花费,对于 $i \gt j$ 的情况,也有 $f[i][j] = 0$。答案即为 $f[1][n]$。 + +对于 $f[i][j]$,我们可以枚举 $[i, j]$ 中的任意一个数 $k$,将区间 $[i, j]$ 分为 $[i, k - 1]$ 和 $[k + 1, j]$ 两部分,选择其中的较大值加上 $k$ 的花费,即 $\max(f[i][k - 1], f[k + 1][j]) + k$ 的最小值。 + +时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为猜测的数字范围。 @@ -99,15 +105,13 @@ tags: ```python class Solution: def getMoneyAmount(self, n: int) -> int: - dp = [[0] * (n + 10) for _ in range(n + 10)] - for l in range(2, n + 1): - for i in range(1, n - l + 2): - j = i + l - 1 - dp[i][j] = inf - for k in range(i, j + 1): - t = max(dp[i][k - 1], dp[k + 1][j]) + k - dp[i][j] = min(dp[i][j], t) - return dp[1][n] + f = [[0] * (n + 1) for _ in range(n + 1)] + for i in range(n - 1, 0, -1): + for j in range(i + 1, n + 1): + f[i][j] = j + f[i][j - 1] + for k in range(i, j): + f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k) + return f[1][n] ``` #### Java @@ -115,18 +119,16 @@ class Solution: ```java class Solution { public int getMoneyAmount(int n) { - int[][] dp = new int[n + 10][n + 10]; - for (int l = 2; l <= n; ++l) { - for (int i = 1; i + l - 1 <= n; ++i) { - int j = i + l - 1; - dp[i][j] = Integer.MAX_VALUE; - for (int k = i; k <= j; ++k) { - int t = Math.max(dp[i][k - 1], dp[k + 1][j]) + k; - dp[i][j] = Math.min(dp[i][j], t); + int[][] f = new int[n + 1][n + 1]; + for (int i = n - 1; i > 0; --i) { + for (int j = i + 1; j <= n; ++j) { + f[i][j] = j + f[i][j - 1]; + for (int k = i; k < j; ++k) { + f[i][j] = Math.min(f[i][j], Math.max(f[i][k - 1], f[k + 1][j]) + k); } } } - return dp[1][n]; + return f[1][n]; } } ``` @@ -137,18 +139,17 @@ class Solution { class Solution { public: int getMoneyAmount(int n) { - vector> dp(n + 10, vector(n + 10)); - for (int l = 2; l <= n; ++l) { - for (int i = 1; i + l - 1 <= n; ++i) { - int j = i + l - 1; - dp[i][j] = INT_MAX; - for (int k = i; k <= j; ++k) { - int t = max(dp[i][k - 1], dp[k + 1][j]) + k; - dp[i][j] = min(dp[i][j], t); + int f[n + 1][n + 1]; + memset(f, 0, sizeof(f)); + for (int i = n - 1; i; --i) { + for (int j = i + 1; j <= n; ++j) { + f[i][j] = j + f[i][j - 1]; + for (int k = i; k < j; ++k) { + f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k); } } } - return dp[1][n]; + return f[1][n]; } }; ``` @@ -157,21 +158,36 @@ public: ```go func getMoneyAmount(n int) int { - dp := make([][]int, n+10) - for i := 0; i < len(dp); i++ { - dp[i] = make([]int, n+10) + f := make([][]int, n+1) + for i := range f { + f[i] = make([]int, n+1) } - for l := 2; l <= n; l++ { - for i := 1; i+l-1 <= n; i++ { - j := i + l - 1 - dp[i][j] = math.MaxInt32 - for k := i; k <= j; k++ { - t := max(dp[i][k-1], dp[k+1][j]) + k - dp[i][j] = min(dp[i][j], t) + for i := n - 1; i > 0; i-- { + for j := i + 1; j <= n; j++ { + f[i][j] = j + f[i][j-1] + for k := i; k < j; k++ { + f[i][j] = min(f[i][j], k+max(f[i][k-1], f[k+1][j])) } } } - return dp[1][n] + return f[1][n] +} +``` + +#### TypeScript + +```ts +function getMoneyAmount(n: number): number { + const f: number[][] = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0)); + for (let i = n - 1; i; --i) { + for (let j = i + 1; j <= n; ++j) { + f[i][j] = j + f[i][j - 1]; + for (let k = i; k < j; ++k) { + f[i][j] = Math.min(f[i][j], k + Math.max(f[i][k - 1], f[k + 1][j])); + } + } + } + return f[1][n]; } ``` diff --git a/solution/0300-0399/0375.Guess Number Higher or Lower II/README_EN.md b/solution/0300-0399/0375.Guess Number Higher or Lower II/README_EN.md index 48bd4546a173b..2387fa8895409 100644 --- a/solution/0300-0399/0375.Guess Number Higher or Lower II/README_EN.md +++ b/solution/0300-0399/0375.Guess Number Higher or Lower II/README_EN.md @@ -88,7 +88,11 @@ The worst case is that you pay $1. -### Solution 1 +### Solution 1: Dynamic Programming + +We define $f[i][j]$ as the minimum cost required to guess any number in the interval $[i, j]$. Initially, $f[i][i] = 0$ because there is no cost to guess the only number, and for $i > j$, we also have $f[i][j] = 0$. The answer is $f[1][n]$. + +For $f[i][j]$, we can enumerate any number $k$ in $[i, j]$, divide the interval $[i, j]$ into two parts, $[i, k - 1]$ and $[k + 1, j]$, choose the larger value of the two parts plus the cost of $k$, @@ -97,15 +101,13 @@ The worst case is that you pay $1. ```python class Solution: def getMoneyAmount(self, n: int) -> int: - dp = [[0] * (n + 10) for _ in range(n + 10)] - for l in range(2, n + 1): - for i in range(1, n - l + 2): - j = i + l - 1 - dp[i][j] = inf - for k in range(i, j + 1): - t = max(dp[i][k - 1], dp[k + 1][j]) + k - dp[i][j] = min(dp[i][j], t) - return dp[1][n] + f = [[0] * (n + 1) for _ in range(n + 1)] + for i in range(n - 1, 0, -1): + for j in range(i + 1, n + 1): + f[i][j] = j + f[i][j - 1] + for k in range(i, j): + f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k) + return f[1][n] ``` #### Java @@ -113,18 +115,16 @@ class Solution: ```java class Solution { public int getMoneyAmount(int n) { - int[][] dp = new int[n + 10][n + 10]; - for (int l = 2; l <= n; ++l) { - for (int i = 1; i + l - 1 <= n; ++i) { - int j = i + l - 1; - dp[i][j] = Integer.MAX_VALUE; - for (int k = i; k <= j; ++k) { - int t = Math.max(dp[i][k - 1], dp[k + 1][j]) + k; - dp[i][j] = Math.min(dp[i][j], t); + int[][] f = new int[n + 1][n + 1]; + for (int i = n - 1; i > 0; --i) { + for (int j = i + 1; j <= n; ++j) { + f[i][j] = j + f[i][j - 1]; + for (int k = i; k < j; ++k) { + f[i][j] = Math.min(f[i][j], Math.max(f[i][k - 1], f[k + 1][j]) + k); } } } - return dp[1][n]; + return f[1][n]; } } ``` @@ -135,18 +135,17 @@ class Solution { class Solution { public: int getMoneyAmount(int n) { - vector> dp(n + 10, vector(n + 10)); - for (int l = 2; l <= n; ++l) { - for (int i = 1; i + l - 1 <= n; ++i) { - int j = i + l - 1; - dp[i][j] = INT_MAX; - for (int k = i; k <= j; ++k) { - int t = max(dp[i][k - 1], dp[k + 1][j]) + k; - dp[i][j] = min(dp[i][j], t); + int f[n + 1][n + 1]; + memset(f, 0, sizeof(f)); + for (int i = n - 1; i; --i) { + for (int j = i + 1; j <= n; ++j) { + f[i][j] = j + f[i][j - 1]; + for (int k = i; k < j; ++k) { + f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k); } } } - return dp[1][n]; + return f[1][n]; } }; ``` @@ -155,21 +154,36 @@ public: ```go func getMoneyAmount(n int) int { - dp := make([][]int, n+10) - for i := 0; i < len(dp); i++ { - dp[i] = make([]int, n+10) + f := make([][]int, n+1) + for i := range f { + f[i] = make([]int, n+1) } - for l := 2; l <= n; l++ { - for i := 1; i+l-1 <= n; i++ { - j := i + l - 1 - dp[i][j] = math.MaxInt32 - for k := i; k <= j; k++ { - t := max(dp[i][k-1], dp[k+1][j]) + k - dp[i][j] = min(dp[i][j], t) + for i := n - 1; i > 0; i-- { + for j := i + 1; j <= n; j++ { + f[i][j] = j + f[i][j-1] + for k := i; k < j; k++ { + f[i][j] = min(f[i][j], k+max(f[i][k-1], f[k+1][j])) } } } - return dp[1][n] + return f[1][n] +} +``` + +#### TypeScript + +```ts +function getMoneyAmount(n: number): number { + const f: number[][] = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0)); + for (let i = n - 1; i; --i) { + for (let j = i + 1; j <= n; ++j) { + f[i][j] = j + f[i][j - 1]; + for (let k = i; k < j; ++k) { + f[i][j] = Math.min(f[i][j], k + Math.max(f[i][k - 1], f[k + 1][j])); + } + } + } + return f[1][n]; } ``` diff --git a/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.cpp b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.cpp index d9ba619ccc4a9..12344e6645c67 100644 --- a/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.cpp +++ b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.cpp @@ -1,17 +1,16 @@ class Solution { public: int getMoneyAmount(int n) { - vector> dp(n + 10, vector(n + 10)); - for (int l = 2; l <= n; ++l) { - for (int i = 1; i + l - 1 <= n; ++i) { - int j = i + l - 1; - dp[i][j] = INT_MAX; - for (int k = i; k <= j; ++k) { - int t = max(dp[i][k - 1], dp[k + 1][j]) + k; - dp[i][j] = min(dp[i][j], t); + int f[n + 1][n + 1]; + memset(f, 0, sizeof(f)); + for (int i = n - 1; i; --i) { + for (int j = i + 1; j <= n; ++j) { + f[i][j] = j + f[i][j - 1]; + for (int k = i; k < j; ++k) { + f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k); } } } - return dp[1][n]; + return f[1][n]; } }; \ No newline at end of file diff --git a/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.go b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.go index 60a3fb345611e..b99bd7ffaf773 100644 --- a/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.go +++ b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.go @@ -1,17 +1,15 @@ func getMoneyAmount(n int) int { - dp := make([][]int, n+10) - for i := 0; i < len(dp); i++ { - dp[i] = make([]int, n+10) + f := make([][]int, n+1) + for i := range f { + f[i] = make([]int, n+1) } - for l := 2; l <= n; l++ { - for i := 1; i+l-1 <= n; i++ { - j := i + l - 1 - dp[i][j] = math.MaxInt32 - for k := i; k <= j; k++ { - t := max(dp[i][k-1], dp[k+1][j]) + k - dp[i][j] = min(dp[i][j], t) + for i := n - 1; i > 0; i-- { + for j := i + 1; j <= n; j++ { + f[i][j] = j + f[i][j-1] + for k := i; k < j; k++ { + f[i][j] = min(f[i][j], k+max(f[i][k-1], f[k+1][j])) } } } - return dp[1][n] + return f[1][n] } \ No newline at end of file diff --git a/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.java b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.java index ef986bfcdcf55..a04fc0b0c8b8d 100644 --- a/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.java +++ b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.java @@ -1,16 +1,14 @@ class Solution { public int getMoneyAmount(int n) { - int[][] dp = new int[n + 10][n + 10]; - for (int l = 2; l <= n; ++l) { - for (int i = 1; i + l - 1 <= n; ++i) { - int j = i + l - 1; - dp[i][j] = Integer.MAX_VALUE; - for (int k = i; k <= j; ++k) { - int t = Math.max(dp[i][k - 1], dp[k + 1][j]) + k; - dp[i][j] = Math.min(dp[i][j], t); + int[][] f = new int[n + 1][n + 1]; + for (int i = n - 1; i > 0; --i) { + for (int j = i + 1; j <= n; ++j) { + f[i][j] = j + f[i][j - 1]; + for (int k = i; k < j; ++k) { + f[i][j] = Math.min(f[i][j], Math.max(f[i][k - 1], f[k + 1][j]) + k); } } } - return dp[1][n]; + return f[1][n]; } } \ No newline at end of file diff --git a/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.py b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.py index 7b055add2701a..52e291e3831e0 100644 --- a/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.py +++ b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.py @@ -1,11 +1,9 @@ class Solution: def getMoneyAmount(self, n: int) -> int: - dp = [[0] * (n + 10) for _ in range(n + 10)] - for l in range(2, n + 1): - for i in range(1, n - l + 2): - j = i + l - 1 - dp[i][j] = inf - for k in range(i, j + 1): - t = max(dp[i][k - 1], dp[k + 1][j]) + k - dp[i][j] = min(dp[i][j], t) - return dp[1][n] + f = [[0] * (n + 1) for _ in range(n + 1)] + for i in range(n - 1, 0, -1): + for j in range(i + 1, n + 1): + f[i][j] = j + f[i][j - 1] + for k in range(i, j): + f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k) + return f[1][n] diff --git a/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.ts b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.ts new file mode 100644 index 0000000000000..6d1d678467f19 --- /dev/null +++ b/solution/0300-0399/0375.Guess Number Higher or Lower II/Solution.ts @@ -0,0 +1,12 @@ +function getMoneyAmount(n: number): number { + const f: number[][] = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0)); + for (let i = n - 1; i; --i) { + for (let j = i + 1; j <= n; ++j) { + f[i][j] = j + f[i][j - 1]; + for (let k = i; k < j; ++k) { + f[i][j] = Math.min(f[i][j], k + Math.max(f[i][k - 1], f[k + 1][j])); + } + } + } + return f[1][n]; +} diff --git a/solution/0300-0399/0376.Wiggle Subsequence/README.md b/solution/0300-0399/0376.Wiggle Subsequence/README.md index 8a555a50904fb..c6e46d233827e 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/README.md +++ b/solution/0300-0399/0376.Wiggle Subsequence/README.md @@ -76,7 +76,15 @@ tags: -### 方法一 +### 方法一:动态规划 + +我们定义 $f[i]$ 表示以第 $i$ 个元素结尾且最后是上升趋势的摆动序列的长度,定义 $g[i]$ 表示以第 $i$ 个元素结尾且最后是下降趋势的摆动序列的长度。初始时 $f[0] = g[0] = 1$,因为只有一个元素时,摆动序列的长度为 $1$。初始化答案为 $1$。 + +对于 $f[i]$,其中 $i \geq 1$,我们在 $[0, i)$ 的范围内枚举 $j$,如果 $nums[j] < nums[i]$,则说明 $i$ 可以接在 $j$ 的后面形成一个上升的摆动序列,此时 $f[i] = \max(f[i], g[j] + 1)$;如果 $nums[j] > nums[i]$,则说明 $i$ 可以接在 $j$ 的后面形成一个下降的摆动序列,此时 $g[i] = \max(g[i], f[j] + 1)$。然后我们更新答案为 $\max(f[i], g[i])$。 + +最后,我们返回答案。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。 @@ -85,13 +93,18 @@ tags: ```python class Solution: def wiggleMaxLength(self, nums: List[int]) -> int: - up = down = 1 - for i in range(1, len(nums)): - if nums[i] > nums[i - 1]: - up = max(up, down + 1) - elif nums[i] < nums[i - 1]: - down = max(down, up + 1) - return max(up, down) + n = len(nums) + ans = 1 + f = [1] * n + g = [1] * n + for i in range(1, n): + for j in range(i): + if nums[j] < nums[i]: + f[i] = max(f[i], g[j] + 1) + elif nums[j] > nums[i]: + g[i] = max(g[i], f[j] + 1) + ans = max(ans, f[i], g[i]) + return ans ``` #### Java @@ -99,15 +112,23 @@ class Solution: ```java class Solution { public int wiggleMaxLength(int[] nums) { - int up = 1, down = 1; - for (int i = 1; i < nums.length; ++i) { - if (nums[i] > nums[i - 1]) { - up = Math.max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = Math.max(down, up + 1); + int n = nums.length; + int ans = 1; + int[] f = new int[n]; + int[] g = new int[n]; + f[0] = 1; + g[0] = 1; + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[j] < nums[i]) { + f[i] = Math.max(f[i], g[j] + 1); + } else if (nums[j] > nums[i]) { + g[i] = Math.max(g[i], f[j] + 1); + } } + ans = Math.max(ans, Math.max(f[i], g[i])); } - return Math.max(up, down); + return ans; } } ``` @@ -118,15 +139,21 @@ class Solution { class Solution { public: int wiggleMaxLength(vector& nums) { - int up = 1, down = 1; - for (int i = 1; i < nums.size(); ++i) { - if (nums[i] > nums[i - 1]) { - up = max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = max(down, up + 1); + int n = nums.size(); + int ans = 1; + vector f(n, 1); + vector g(n, 1); + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[j] < nums[i]) { + f[i] = max(f[i], g[j] + 1); + } else if (nums[j] > nums[i]) { + g[i] = max(g[i], f[j] + 1); + } } + ans = max({ans, f[i], g[i]}); } - return max(up, down); + return ans; } }; ``` @@ -135,15 +162,22 @@ public: ```go func wiggleMaxLength(nums []int) int { - up, down := 1, 1 - for i := 1; i < len(nums); i++ { - if nums[i] > nums[i-1] { - up = max(up, down+1) - } else if nums[i] < nums[i-1] { - down = max(down, up+1) + n := len(nums) + f := make([]int, n) + g := make([]int, n) + f[0], g[0] = 1, 1 + ans := 1 + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + if nums[j] < nums[i] { + f[i] = max(f[i], g[j]+1) + } else if nums[j] > nums[i] { + g[i] = max(g[i], f[j]+1) + } } + ans = max(ans, max(f[i], g[i])) } - return max(up, down) + return ans } ``` @@ -151,18 +185,21 @@ func wiggleMaxLength(nums []int) int { ```ts function wiggleMaxLength(nums: number[]): number { - let up = 1, - down = 1; - for (let i = 1; i < nums.length; ++i) { - let prev = nums[i - 1], - cur = nums[i]; - if (cur > prev) { - up = Math.max(up, down + 1); - } else if (cur < prev) { - down = Math.max(down, up + 1); + const n = nums.length; + const f: number[] = Array(n).fill(1); + const g: number[] = Array(n).fill(1); + let ans = 1; + for (let i = 1; i < n; ++i) { + for (let j = 0; j < i; ++j) { + if (nums[i] > nums[j]) { + f[i] = Math.max(f[i], g[j] + 1); + } else if (nums[i] < nums[j]) { + g[i] = Math.max(g[i], f[j] + 1); + } } + ans = Math.max(ans, f[i], g[i]); } - return Math.max(up, down); + return ans; } ``` diff --git a/solution/0300-0399/0376.Wiggle Subsequence/README_EN.md b/solution/0300-0399/0376.Wiggle Subsequence/README_EN.md index 3326f86ee786c..36775b6b9cf67 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/README_EN.md +++ b/solution/0300-0399/0376.Wiggle Subsequence/README_EN.md @@ -71,7 +71,15 @@ One is [1, 17, 10, 13, 10, 16, 8] with differences (16, -7, 3, -3, 6, -8). -### Solution 1 +### Solution 1: Dynamic Programming + +We define $f[i]$ as the length of the wiggle sequence ending at the $i$th element with an upward trend, and $g[i]$ as the length of the wiggle sequence ending at the $i$th element with a downward trend. Initially, $f[0] = g[0] = 1$ because when there is only one element, the length of the wiggle sequence is $1$. Initialize the answer as $1$. + +For $f[i]$, where $i \geq 1$, we enumerate $j$ in the range $[0, i)$, if $nums[j] < nums[i]$, it means that $i$ can be appended after $j$ to form an upward wiggle sequence, then $f[i] = \max(f[i], g[j] + 1)$; if $nums[j] > nums[i]$, it means that $i$ can be appended after $j$ to form a downward wiggle sequence, then $g[i] = \max(g[i], f[j] + 1)$. Then we update the answer to $\max(f[i], g[i])$. + +Finally, we return the answer. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Where $n$ is the length of the array $nums$. @@ -80,13 +88,18 @@ One is [1, 17, 10, 13, 10, 16, 8] with differences (16, -7, 3, -3, 6, -8). ```python class Solution: def wiggleMaxLength(self, nums: List[int]) -> int: - up = down = 1 - for i in range(1, len(nums)): - if nums[i] > nums[i - 1]: - up = max(up, down + 1) - elif nums[i] < nums[i - 1]: - down = max(down, up + 1) - return max(up, down) + n = len(nums) + ans = 1 + f = [1] * n + g = [1] * n + for i in range(1, n): + for j in range(i): + if nums[j] < nums[i]: + f[i] = max(f[i], g[j] + 1) + elif nums[j] > nums[i]: + g[i] = max(g[i], f[j] + 1) + ans = max(ans, f[i], g[i]) + return ans ``` #### Java @@ -94,15 +107,23 @@ class Solution: ```java class Solution { public int wiggleMaxLength(int[] nums) { - int up = 1, down = 1; - for (int i = 1; i < nums.length; ++i) { - if (nums[i] > nums[i - 1]) { - up = Math.max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = Math.max(down, up + 1); + int n = nums.length; + int ans = 1; + int[] f = new int[n]; + int[] g = new int[n]; + f[0] = 1; + g[0] = 1; + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[j] < nums[i]) { + f[i] = Math.max(f[i], g[j] + 1); + } else if (nums[j] > nums[i]) { + g[i] = Math.max(g[i], f[j] + 1); + } } + ans = Math.max(ans, Math.max(f[i], g[i])); } - return Math.max(up, down); + return ans; } } ``` @@ -113,15 +134,21 @@ class Solution { class Solution { public: int wiggleMaxLength(vector& nums) { - int up = 1, down = 1; - for (int i = 1; i < nums.size(); ++i) { - if (nums[i] > nums[i - 1]) { - up = max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = max(down, up + 1); + int n = nums.size(); + int ans = 1; + vector f(n, 1); + vector g(n, 1); + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[j] < nums[i]) { + f[i] = max(f[i], g[j] + 1); + } else if (nums[j] > nums[i]) { + g[i] = max(g[i], f[j] + 1); + } } + ans = max({ans, f[i], g[i]}); } - return max(up, down); + return ans; } }; ``` @@ -130,15 +157,22 @@ public: ```go func wiggleMaxLength(nums []int) int { - up, down := 1, 1 - for i := 1; i < len(nums); i++ { - if nums[i] > nums[i-1] { - up = max(up, down+1) - } else if nums[i] < nums[i-1] { - down = max(down, up+1) + n := len(nums) + f := make([]int, n) + g := make([]int, n) + f[0], g[0] = 1, 1 + ans := 1 + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + if nums[j] < nums[i] { + f[i] = max(f[i], g[j]+1) + } else if nums[j] > nums[i] { + g[i] = max(g[i], f[j]+1) + } } + ans = max(ans, max(f[i], g[i])) } - return max(up, down) + return ans } ``` @@ -146,18 +180,21 @@ func wiggleMaxLength(nums []int) int { ```ts function wiggleMaxLength(nums: number[]): number { - let up = 1, - down = 1; - for (let i = 1; i < nums.length; ++i) { - let prev = nums[i - 1], - cur = nums[i]; - if (cur > prev) { - up = Math.max(up, down + 1); - } else if (cur < prev) { - down = Math.max(down, up + 1); + const n = nums.length; + const f: number[] = Array(n).fill(1); + const g: number[] = Array(n).fill(1); + let ans = 1; + for (let i = 1; i < n; ++i) { + for (let j = 0; j < i; ++j) { + if (nums[i] > nums[j]) { + f[i] = Math.max(f[i], g[j] + 1); + } else if (nums[i] < nums[j]) { + g[i] = Math.max(g[i], f[j] + 1); + } } + ans = Math.max(ans, f[i], g[i]); } - return Math.max(up, down); + return ans; } ``` diff --git a/solution/0300-0399/0376.Wiggle Subsequence/Solution.cpp b/solution/0300-0399/0376.Wiggle Subsequence/Solution.cpp index c4cc9f807f91d..edf3b004b10bb 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/Solution.cpp +++ b/solution/0300-0399/0376.Wiggle Subsequence/Solution.cpp @@ -1,14 +1,20 @@ -class Solution { -public: - int wiggleMaxLength(vector& nums) { - int up = 1, down = 1; - for (int i = 1; i < nums.size(); ++i) { - if (nums[i] > nums[i - 1]) { - up = max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = max(down, up + 1); - } - } - return max(up, down); - } +class Solution { +public: + int wiggleMaxLength(vector& nums) { + int n = nums.size(); + int ans = 1; + vector f(n, 1); + vector g(n, 1); + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[j] < nums[i]) { + f[i] = max(f[i], g[j] + 1); + } else if (nums[j] > nums[i]) { + g[i] = max(g[i], f[j] + 1); + } + } + ans = max({ans, f[i], g[i]}); + } + return ans; + } }; \ No newline at end of file diff --git a/solution/0300-0399/0376.Wiggle Subsequence/Solution.go b/solution/0300-0399/0376.Wiggle Subsequence/Solution.go index 38c941722eb37..abccabf21a64b 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/Solution.go +++ b/solution/0300-0399/0376.Wiggle Subsequence/Solution.go @@ -1,11 +1,18 @@ -func wiggleMaxLength(nums []int) int { - up, down := 1, 1 - for i := 1; i < len(nums); i++ { - if nums[i] > nums[i-1] { - up = max(up, down+1) - } else if nums[i] < nums[i-1] { - down = max(down, up+1) - } - } - return max(up, down) +func wiggleMaxLength(nums []int) int { + n := len(nums) + f := make([]int, n) + g := make([]int, n) + f[0], g[0] = 1, 1 + ans := 1 + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + if nums[j] < nums[i] { + f[i] = max(f[i], g[j]+1) + } else if nums[j] > nums[i] { + g[i] = max(g[i], f[j]+1) + } + } + ans = max(ans, max(f[i], g[i])) + } + return ans } \ No newline at end of file diff --git a/solution/0300-0399/0376.Wiggle Subsequence/Solution.java b/solution/0300-0399/0376.Wiggle Subsequence/Solution.java index c344740ff32a5..a21ecedb5f951 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/Solution.java +++ b/solution/0300-0399/0376.Wiggle Subsequence/Solution.java @@ -1,13 +1,21 @@ -class Solution { - public int wiggleMaxLength(int[] nums) { - int up = 1, down = 1; - for (int i = 1; i < nums.length; ++i) { - if (nums[i] > nums[i - 1]) { - up = Math.max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = Math.max(down, up + 1); - } - } - return Math.max(up, down); - } +class Solution { + public int wiggleMaxLength(int[] nums) { + int n = nums.length; + int ans = 1; + int[] f = new int[n]; + int[] g = new int[n]; + f[0] = 1; + g[0] = 1; + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[j] < nums[i]) { + f[i] = Math.max(f[i], g[j] + 1); + } else if (nums[j] > nums[i]) { + g[i] = Math.max(g[i], f[j] + 1); + } + } + ans = Math.max(ans, Math.max(f[i], g[i])); + } + return ans; + } } \ No newline at end of file diff --git a/solution/0300-0399/0376.Wiggle Subsequence/Solution.py b/solution/0300-0399/0376.Wiggle Subsequence/Solution.py index 175ef70797925..0c4d352cb3209 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/Solution.py +++ b/solution/0300-0399/0376.Wiggle Subsequence/Solution.py @@ -1,9 +1,14 @@ -class Solution: - def wiggleMaxLength(self, nums: List[int]) -> int: - up = down = 1 - for i in range(1, len(nums)): - if nums[i] > nums[i - 1]: - up = max(up, down + 1) - elif nums[i] < nums[i - 1]: - down = max(down, up + 1) - return max(up, down) +class Solution: + def wiggleMaxLength(self, nums: List[int]) -> int: + n = len(nums) + ans = 1 + f = [1] * n + g = [1] * n + for i in range(1, n): + for j in range(i): + if nums[j] < nums[i]: + f[i] = max(f[i], g[j] + 1) + elif nums[j] > nums[i]: + g[i] = max(g[i], f[j] + 1) + ans = max(ans, f[i], g[i]) + return ans diff --git a/solution/0300-0399/0376.Wiggle Subsequence/Solution.ts b/solution/0300-0399/0376.Wiggle Subsequence/Solution.ts index b093a00f6586a..86ef58e4aa0f0 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/Solution.ts +++ b/solution/0300-0399/0376.Wiggle Subsequence/Solution.ts @@ -1,14 +1,17 @@ function wiggleMaxLength(nums: number[]): number { - let up = 1, - down = 1; - for (let i = 1; i < nums.length; ++i) { - let prev = nums[i - 1], - cur = nums[i]; - if (cur > prev) { - up = Math.max(up, down + 1); - } else if (cur < prev) { - down = Math.max(down, up + 1); + const n = nums.length; + const f: number[] = Array(n).fill(1); + const g: number[] = Array(n).fill(1); + let ans = 1; + for (let i = 1; i < n; ++i) { + for (let j = 0; j < i; ++j) { + if (nums[i] > nums[j]) { + f[i] = Math.max(f[i], g[j] + 1); + } else if (nums[i] < nums[j]) { + g[i] = Math.max(g[i], f[j] + 1); + } } + ans = Math.max(ans, f[i], g[i]); } - return Math.max(up, down); + return ans; } diff --git a/solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README.md b/solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README.md index ce9137d070834..12fb5b90c0f91 100644 --- a/solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README.md +++ b/solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README.md @@ -77,7 +77,7 @@ tags: 相似题目: -- [3171. 找到按位与最接近 K 的子数组](/solution/3100-3199/3171.Find%20Subarray%20With%20Bitwise%20AND%20Closest%20to%20K/README.md) +- [3171. 找到按位与最接近 K 的子数组](https://github.com/doocs/leetcode/blob/main/solution/3100-3199/3171.Find%20Subarray%20With%20Bitwise%20AND%20Closest%20to%20K/README.md) diff --git a/solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README_EN.md b/solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README_EN.md index 55c8351e6128e..6eb73136bcf37 100644 --- a/solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README_EN.md +++ b/solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README_EN.md @@ -78,7 +78,7 @@ The time complexity is $O(n \times \log M)$, and the space complexity is $O(\log Similar problems: -- [3171. Find Subarray With Bitwise AND Closest to K](/solution/3100-3199/3171.Find%20Subarray%20With%20Bitwise%20AND%20Closest%20to%20K/README_EN.md) +- [3171. Find Subarray With Bitwise AND Closest to K](https://github.com/doocs/leetcode/blob/main/solution/3100-3199/3171.Find%20Subarray%20With%20Bitwise%20AND%20Closest%20to%20K/README_EN.md) diff --git a/solution/3000-3099/3097.Shortest Subarray With OR at Least K II/README.md b/solution/3000-3099/3097.Shortest Subarray With OR at Least K II/README.md index a6708c144a9d7..d059a36144dd9 100644 --- a/solution/3000-3099/3097.Shortest Subarray With OR at Least K II/README.md +++ b/solution/3000-3099/3097.Shortest Subarray With OR at Least K II/README.md @@ -94,7 +94,7 @@ tags: 相似题目: -- [3171. 找到按位与最接近 K 的子数组](/solution/3100-3199/3171.Find%20Subarray%20With%20Bitwise%20AND%20Closest%20to%20K/README.md) +- [3171. 找到按位与最接近 K 的子数组](https://github.com/doocs/leetcode/blob/main/solution/3100-3199/3171.Find%20Subarray%20With%20Bitwise%20AND%20Closest%20to%20K/README.md) diff --git a/solution/3000-3099/3097.Shortest Subarray With OR at Least K II/README_EN.md b/solution/3000-3099/3097.Shortest Subarray With OR at Least K II/README_EN.md index d959b60b582ad..5ccced4140e6c 100644 --- a/solution/3000-3099/3097.Shortest Subarray With OR at Least K II/README_EN.md +++ b/solution/3000-3099/3097.Shortest Subarray With OR at Least K II/README_EN.md @@ -92,7 +92,7 @@ The time complexity is $O(n \times \log M)$ and the space complexity is $O(\log Similar Problems: -- [3171. Find Subarray With Bitwise AND Closest to K](/solution/3100-3199/3171.Find%20Subarray%20With%20Bitwise%20AND%20Closest%20to%20K/README_EN.md) +- [3171. Find Subarray With Bitwise AND Closest to K](https://github.com/doocs/leetcode/blob/main/solution/3100-3199/3171.Find%20Subarray%20With%20Bitwise%20AND%20Closest%20to%20K/README_EN.md) diff --git a/solution/3100-3199/3171.Find Subarray With Bitwise AND Closest to K/README.md b/solution/3100-3199/3171.Find Subarray With Bitwise AND Closest to K/README.md index 2ee4b9b7f8f56..57d1c220238ae 100644 --- a/solution/3100-3199/3171.Find Subarray With Bitwise AND Closest to K/README.md +++ b/solution/3100-3199/3171.Find Subarray With Bitwise AND Closest to K/README.md @@ -84,7 +84,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3100-3199/3171.Fi 相似题目: -- [3097. 或值至少为 K 的最短子数组 II](/solution/3000-3099/3097.Shortest%20Subarray%20With%20OR%20at%20Least%20K%20II/README.md) +- [3097. 或值至少为 K 的最短子数组 II](https://github.com/doocs/leetcode/blob/main/solution/3000-3099/3097.Shortest%20Subarray%20With%20OR%20at%20Least%20K%20II/README.md) @@ -272,7 +272,7 @@ function minimumDifference(nums: number[], k: number): number { 相似题目: -- [1521. 找到最接近目标值的函数值](/solution/1500-1599/1521.Find%20a%20Value%20of%20a%20Mysterious%20Function%20Closest%20to%20Target/README.md) +- [1521. 找到最接近目标值的函数值](https://github.com/doocs/leetcode/blob/main/solution/1500-1599/1521.Find%20a%20Value%20of%20a%20Mysterious%20Function%20Closest%20to%20Target/README.md) diff --git a/solution/3100-3199/3171.Find Subarray With Bitwise AND Closest to K/README_EN.md b/solution/3100-3199/3171.Find Subarray With Bitwise AND Closest to K/README_EN.md index 40ca22b68a570..35dd0ef711547 100644 --- a/solution/3100-3199/3171.Find Subarray With Bitwise AND Closest to K/README_EN.md +++ b/solution/3100-3199/3171.Find Subarray With Bitwise AND Closest to K/README_EN.md @@ -82,7 +82,7 @@ The time complexity is $O(n \times \log M)$, and the space complexity is $O(\log Similar Problems: -- [3097. Shortest Subarray With OR at Least K II](/solution/3000-3099/3097.Shortest%20Subarray%20With%20OR%20at%20Least%20K%20II/README_EN.md) +- [3097. Shortest Subarray With OR at Least K II](https://github.com/doocs/leetcode/blob/main/solution/3000-3099/3097.Shortest%20Subarray%20With%20OR%20at%20Least%20K%20II/README_EN.md) @@ -270,7 +270,7 @@ The time complexity is $O(n \times \log M)$, and the space complexity is $O(\log Similar problems: -- [1521. Find a Value of a Mysterious Function Closest to Target](/solution/1500-1599/1521.Find%20a%20Value%20of%20a%20Mysterious%20Function%20Closest%20to%20Target/README_EN.md) +- [1521. Find a Value of a Mysterious Function Closest to Target](https://github.com/doocs/leetcode/blob/main/solution/1500-1599/1521.Find%20a%20Value%20of%20a%20Mysterious%20Function%20Closest%20to%20Target/README_EN.md)