classSolution { staticconstint MAX = 1e5 + 5; int open[MAX], close[MAX], dot[MAX]; public: intminMoves(vector<int>& nums, int limit){ // 统计和的最大众数,变其他。但是有的需要大于limit (x) // 二分,快速求判定问题? // 暴力,枚举互补数,遍历一遍再。O(n * n) // a + b = 互补数,0 // a + b 变 互补数: 1, 2 // 0次变 是一个数 // 一次变最大,一次变最小 是一个范围 // 出了范围就需要2次变 // 确定互补数,可以遍历一遍确定变数 // 确定变数呢? // | . | // open - close: in range // close + total - open: out range // dtop: 0 constint n = nums.size(); for (int i = 0; i < n - 1 - i; ++i) { int a = nums[i]; int b = nums[n - 1 - i]; if (a > b) swap(a, b); // a <= b int lower = a + 1; int upper = b + limit; dot[i] = a + b; open[i] = lower; close[i] = upper; } constint size = n / 2; auto openEnd = begin(open) + size; auto closeEnd = begin(close) + size; auto dotEnd = begin(dot) + size; sort(begin(open), openEnd); sort(begin(close), closeEnd); sort(begin(dot), dotEnd); auto need = [&](constint line) -> int { auto itOpen = upper_bound(begin(open), openEnd, line); auto itClose = lower_bound(begin(close), closeEnd, line); auto itDot = lower_bound(begin(dot), dotEnd, line); auto itDot2 = upper_bound(itDot, dotEnd, line); int dotNumber = distance(itDot, itDot2); int outRange = 0; outRange += distance(begin(close), itClose); outRange += distance(itOpen, openEnd); int inRange = n / 2 - dotNumber - outRange; return inRange + 2 * outRange; }; int ans = n; for (int line = 2; line <= limit * 2; ++line) { constint condidate = need(line); // cout << line << ": " << condidate << endl; ans = min(ans, condidate); } return ans; } };