|
55 | 55 |
|
56 | 56 | <!-- 这里可写通用的实现逻辑 -->
|
57 | 57 |
|
| 58 | +**方法一:动态规划** |
| 59 | + |
| 60 | +我们定义 $f[i]$ 表示从前 $i$ 个元素中选出的子序列,且最后一个元素为奇数下标时的最大交替和,定义 $g[i]$ 表示从前 $i$ 个元素中选出的子序列,且最后一个元素为偶数下标时的最大交替和。初始时 $f[0] = g[0] = 0$。答案为 $max(f[n], g[n])$。 |
| 61 | + |
| 62 | +我们考虑第 $i$ 个元素 $nums[i - 1]$: |
| 63 | + |
| 64 | +如果选取该元素且该元素为奇数下标,那么上一个元素必须为偶数下标,且只能从前 $i-1$ 个元素中选取,因此 $f[i] = g[i - 1] - nums[i - 1]$;如果不选取该元素,那么 $f[i] = f[i - 1]$。 |
| 65 | + |
| 66 | +同理,如果选取该元素且该元素为偶数下标,那么上一个元素必须为奇数下标,且只能从前 $i-1$ 个元素中选取,因此 $g[i] = f[i - 1] + nums[i - 1]$;如果不选取该元素,那么 $g[i] = g[i - 1]$。 |
| 67 | + |
| 68 | +综上,我们可以得到状态转移方程: |
| 69 | + |
| 70 | +$$ |
| 71 | +\begin{aligned} |
| 72 | +f[i] &= max(g[i - 1] - nums[i - 1], f[i - 1]) \\ |
| 73 | +g[i] &= max(f[i - 1] + nums[i - 1], g[i - 1]) |
| 74 | +\end{aligned} |
| 75 | +$$ |
| 76 | + |
| 77 | +最终答案为 $max(f[n], g[n])$。 |
| 78 | + |
| 79 | +我们注意到 $f[i]$ 和 $g[i]$ 只与 $f[i - 1]$ 和 $g[i - 1]$ 有关,因此我们可以使用两个变量代替数组,将空间复杂度降低到 $O(1)$。 |
| 80 | + |
| 81 | +时间复杂度 $O(n)$,其中 $n$ 为数组长度。 |
| 82 | + |
58 | 83 | <!-- tabs:start -->
|
59 | 84 |
|
60 | 85 | ### **Python3**
|
61 | 86 |
|
62 | 87 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
63 | 88 |
|
64 | 89 | ```python
|
| 90 | +class Solution: |
| 91 | + def maxAlternatingSum(self, nums: List[int]) -> int: |
| 92 | + n = len(nums) |
| 93 | + f = [0] * (n + 1) |
| 94 | + g = [0] * (n + 1) |
| 95 | + for i, x in enumerate(nums, 1): |
| 96 | + f[i] = max(g[i - 1] - x, f[i - 1]) |
| 97 | + g[i] = max(f[i - 1] + x, g[i - 1]) |
| 98 | + return max(f[n], g[n]) |
| 99 | +``` |
65 | 100 |
|
| 101 | +```python |
| 102 | +class Solution: |
| 103 | + def maxAlternatingSum(self, nums: List[int]) -> int: |
| 104 | + f = g = 0 |
| 105 | + for x in nums: |
| 106 | + f, g = max(g - x, f), max(f + x, g) |
| 107 | + return max(f, g) |
66 | 108 | ```
|
67 | 109 |
|
68 | 110 | ### **Java**
|
69 | 111 |
|
70 | 112 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
71 | 113 |
|
72 | 114 | ```java
|
| 115 | +class Solution { |
| 116 | + public long maxAlternatingSum(int[] nums) { |
| 117 | + int n = nums.length; |
| 118 | + long[] f = new long[n + 1]; |
| 119 | + long[] g = new long[n + 1]; |
| 120 | + for (int i = 1; i <= n; ++i) { |
| 121 | + f[i] = Math.max(g[i - 1] - nums[i - 1], f[i - 1]); |
| 122 | + g[i] = Math.max(f[i - 1] + nums[i - 1], g[i - 1]); |
| 123 | + } |
| 124 | + return Math.max(f[n], g[n]); |
| 125 | + } |
| 126 | +} |
| 127 | +``` |
| 128 | + |
| 129 | +```java |
| 130 | +class Solution { |
| 131 | + public long maxAlternatingSum(int[] nums) { |
| 132 | + long f = 0, g = 0; |
| 133 | + for (int x : nums) { |
| 134 | + long ff = Math.max(g - x, f); |
| 135 | + long gg = Math.max(f + x, g); |
| 136 | + f = ff; |
| 137 | + g = gg; |
| 138 | + } |
| 139 | + return Math.max(f, g); |
| 140 | + } |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +### **C++** |
| 145 | + |
| 146 | +```cpp |
| 147 | +class Solution { |
| 148 | +public: |
| 149 | + long long maxAlternatingSum(vector<int>& nums) { |
| 150 | + int n = nums.size(); |
| 151 | + vector<long long> f(n + 1), g(n + 1); |
| 152 | + for (int i = 1; i <= n; ++i) { |
| 153 | + f[i] = max(g[i - 1] - nums[i - 1], f[i - 1]); |
| 154 | + g[i] = max(f[i - 1] + nums[i - 1], g[i - 1]); |
| 155 | + } |
| 156 | + return max(f[n], g[n]); |
| 157 | + } |
| 158 | +}; |
| 159 | +``` |
| 160 | +
|
| 161 | +```cpp |
| 162 | +class Solution { |
| 163 | +public: |
| 164 | + long long maxAlternatingSum(vector<int>& nums) { |
| 165 | + long long f = 0, g = 0; |
| 166 | + for (int& x : nums) { |
| 167 | + long ff = max(g - x, f), gg = max(f + x, g); |
| 168 | + f = ff, g = gg; |
| 169 | + } |
| 170 | + return max(f, g); |
| 171 | + } |
| 172 | +}; |
| 173 | +``` |
| 174 | + |
| 175 | +### **Go** |
| 176 | + |
| 177 | +```go |
| 178 | +func maxAlternatingSum(nums []int) int64 { |
| 179 | + n := len(nums) |
| 180 | + f := make([]int, n+1) |
| 181 | + g := make([]int, n+1) |
| 182 | + for i, x := range nums { |
| 183 | + i++ |
| 184 | + f[i] = max(g[i-1]-x, f[i-1]) |
| 185 | + g[i] = max(f[i-1]+x, g[i-1]) |
| 186 | + } |
| 187 | + return int64(max(f[n], g[n])) |
| 188 | +} |
| 189 | + |
| 190 | +func max(a, b int) int { |
| 191 | + if a > b { |
| 192 | + return a |
| 193 | + } |
| 194 | + return b |
| 195 | +} |
| 196 | +``` |
73 | 197 |
|
| 198 | +```go |
| 199 | +func maxAlternatingSum(nums []int) int64 { |
| 200 | + var f, g int |
| 201 | + for _, x := range nums { |
| 202 | + f, g = max(g-x, f), max(f+x, g) |
| 203 | + } |
| 204 | + return int64(max(f, g)) |
| 205 | +} |
| 206 | + |
| 207 | +func max(a, b int) int { |
| 208 | + if a > b { |
| 209 | + return a |
| 210 | + } |
| 211 | + return b |
| 212 | +} |
74 | 213 | ```
|
75 | 214 |
|
76 | 215 | ### **...**
|
|
0 commit comments