Algorithm (Dynamic programming)
- Let $A$ denote the input array, $f(x)$ the value of the array, $\pi_{\text{rev}}(A,i,j)$ be the new array by reversing $A[i:j]$.
- First, we note that reversing the subarray will only change the value around the two end points. This is because $$f(\pi_{\mathrm{rev}}(A,i,j))=\begin{cases}
L+|a_{i-1}-a_{j}|+M+|a_{i}-a_{j+1}|+R & \text{if }i,j\in\{1,…,n-2\}\\\\
L+|a_{0}-a_{j+1}|+R & \text{if }i=0\text{ and }j\in\{1,…,n-1\}\\\\
L+|a_{n-1}-a_{i-1}|+R & \text{if }i\in\{0,…,n-2\}\text{ and }j=n-1
\end{cases}$$ where $$L=\sum_{l=0}^{i-2}|a_{l}-a_{l+1}|,R=\sum_{r=j+1}^{n-2}|a_{r}-a_{r+1}|,M=\sum_{m=j}^{m=i+1}|a_{m}-a_{m-1}|.$$ And for the identity permutation, we have $$f(\pi_{\mathrm{id}}(A,i,j))=\begin{cases}
L+|a_{i-1}-a_{i}|+M+|a_{j}-a_{j+1}|+R & \text{if }i,j\in\{1,…,n-2\}\\\\
L+|a_{j}-a_{j+1}|+R & \text{if }i=0\text{ and }j\in\{1,…,n-1\}\\\\
L+|a_{i}-a_{i-1}|+R & \text{if }i\in\{0,…,n-2\}\text{ and }j=n-1
\end{cases}.$$ Therefore, the difference between of sum after application of reverse permutation to $A[i:j]$ is $$\delta(A,i,j)=\begin{cases}
|a_{i-1}-a_{j}|+|a_{i}-a_{j+1}|-|a_{i-1}-a_{i}|-|a_{j}-a_{j+1}| & \text{if }i,j\in\{1,…,n-2\}\\\\
|a_{0}-a_{j+1}|-|a_{j}-a_{j+1}| & \text{if }i=0\text{ and }j\in\{1,…,n-1\}\\\\
|a_{n-1}-a_{i-1}|-|a_{i}-a_{i-1}| & \text{if }i\in\{0,…,n-2\}\text{ and }j=n-1
\end{cases}.$$
- So the problem is reduced to finding $\max_{i,j\in\{0,…,n-1\}}\delta(A,i,j).$ The last two cases could be solved in a linear scan. And for the first case, we rewrite it is
\begin{align}
|a_{i-1}-a_{j}|+|a_{i}-a_{j+1}|-|a_{i-1}-a_{i}|-|a_{j}-a_{j+1}| & =g(i,f_{1},f_{2})+h(j,f_{1},f_{2})\text{ for some }i\leq j
\end{align}
where $g(i,f_{1},f_{2})=f_{1}a_{i-1}+f_{2}a_{i}-|a_{i-1}-a_{i}|$ and $h(j,f_{1},f_{2})=-f_{1}a_{j}-f_{2}a_{j+1}-|a_{j+1}-a_{j}|.$ Hence, we have
\begin{align}
\max_{i<j}\delta(A,i,j) & =\max_{i<j}[g(i,f_{1},f_{2})+h(j,f_{1},f_{2})]\\
& =\max_{i<j}[\max_{l\in{1,…,i}}g(i,f_{1},f_{2})+\max_{r\in{j,…,n-2}}h(j,f_{1},f_{2})].\label{eq:obj}\tag{1}
\end{align}
Notice that \eqref{eq:obj} suggest that we can evaluate $\max\delta$ using dynamic programming (prefix and suffix sum)
Code
class Solution {
public:
int maxValueAfterReverse(vector<int>& nums) {
const int n = size(nums);
const auto l_delta = [&](int acc = INT_MIN) {
for (int i = 1; i < n; ++i)
acc = std::max(acc, std::abs(nums[i] - nums[0]) - std::abs(nums[i] - nums[i - 1]));
return acc;
}();
const auto r_delta = [&](int acc = INT_MIN) {
for (int i = 0; i < n - 1; ++i)
acc = std::max(acc, std::abs(nums[n - 1] - nums[i]) - std::abs(nums[i + 1] - nums[i]));
return acc;
}();
const auto m_delta = [&](int acc = INT_MIN) {
auto g = [&](int i, int f1, int f2) {
return -std::abs(nums[i - 1] - nums[i]) + f1 * nums[i - 1] + f2 * nums[i];
};
auto h = [&](int j, int f1, int f2) {
return -std::abs(nums[j] - nums[j + 1]) - f1 * nums[j] - f2 * nums[j + 1];
};
const auto f1f2_combo = std::vector<std::pair<int, int>>{{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
const auto g_prefix_max = [&](std::unordered_map<int, std::unordered_map<int, std::vector<int>>> self = {}) {
for (const auto [f1, f2] : f1f2_combo) {
auto acc = std::vector<int>(n, INT_MIN / 2);
for (int i = 1; i < n; ++i) {
if (i == 1)
acc[i] = g(i, f1, f2);
else
acc[i] = std::max(g(i, f1, f2), acc[i - 1]);
}
self[f1][f2] = acc;
}
return self;
}();
const auto h_suffix_max = [&](std::unordered_map<int, std::unordered_map<int, std::vector<int>>> self = {}) {
for (const auto [f1, f2] : f1f2_combo) {
auto acc = std::vector<int>(n, INT_MIN / 2);
for (int i = n - 2; i >= 0; --i) {
if (i == n - 2)
acc[i] = h(i, f1, f2);
else
acc[i] = std::max(acc[i + 1], h(i, f1, f2));
}
self[f1][f2] = acc;
}
return self;
}();
for (const auto [f1, f2] : f1f2_combo)
for (int i = 1; i < n - 1; ++i)
acc = std::max(acc, g_prefix_max.at(f1).at(f2)[i] + h_suffix_max.at(f1).at(f2)[i + 1]);
return acc;
}();
const auto original_sum = [&](int acc = 0) {
for (int i = 0; i + 1 < n; ++i)
acc += std::abs(nums[i] - nums[i + 1]);
return acc;
}();
const auto solution = original_sum + std::max({l_delta, r_delta, m_delta});
return solution;
}
};