目录
一、题目
1、题目描述
2、输入输出
2.1输入
2.2输出
3、原题链接
二、解题报告
1、思路分析
考虑保留的前后缀满足什么特点?
前缀中 1的数目 - 2的数目 = 后缀中 2的数目 - 1的数目
那么我们发现这就是一个两数之和问题
我们哈希表预处理最靠右 前缀中 1的数目 - 2的数目 的位置
然后倒着遍历后缀,计数维护最长前后缀长度即可
2、复杂度
时间复杂度: O(NlogN)(可以将下标映射从而避免map的访问开销)空间复杂度:O(N)
3、代码详解
#include <bits/stdc++.h>
using i64 = long long;
using i32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;
constexpr int inf32 = 1E9 + 7;
constexpr i64 inf64 = 1E18 + 7;
constexpr int P = 998'244'353;
void solve() {
int n;
std::cin >> n;
int m = n * 2;
std::vector<int> a(m);
std::map<int, int> pre, suf;
for (int i = 0; i < m; ++ i) std::cin >> a[i];
for (int i = 0, f = 0; i < n; ++ i) {
f += (a[i] & 1 ? 1 : -1);
pre[f] = i;
}
int res = m;
for (int i = m - 1, f = 0; i >= n; -- i) {
f += (a[i] & 1 ? -1 : 1);
if (pre.contains(f)) {
res = std::min(res, i - pre[f] - 1);
}
if (f == 0)
res = std::min(res, i);
}
if (pre.contains(0))
res = std::min(res, m - pre[0] - 1);
std::cout << res << '\n';
}
auto FIO = []{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
int main () {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int T = 1;
std::cin >> T;
while (T --) {
solve();
}
return 0;
}