程序删除子列表以在C ++中获得k以下和以上相同数量的元素
假设我们有一个称为nums和另一个数字k的数字列表,我们最多可以从列表中删除任何子列表一次。我们必须找到最长的结果列表的长度,以使严格小于k和严格大于k的数字量相同。
因此,如果输入类似于nums=[6、10、8、9、3、5],k=6,则输出将为5,就像我们删除子列表[9]一样,则得到[6,10、8、3、5],并且有两个小于3的数字[3、5]和两个大于6的数字[10、8]。
为了解决这个问题,我们将遵循以下步骤-
定义大小为nums+1的数组v并用0填充
cnt:=0
对于初始化i:=0,当i<nums大小时,更新(将i增加1),执行-
(将cnt减1)
(将cnt增加1)
如果nums[i]<k,则:
否则,当nums[i]>k时:
v[i+1]=cnt
如果v的最后一个元素为0,则返回nums的大小
delta:=v的最后一个元素
定义一张映射
ans:=无限
对于初始化i:=1,当i<=v的大小时,更新(将i增加1),-
ans:=ans和i的最小值-m[v[i]-v的最后一个元素]
如果m[v[i]-v的最后一个元素不等于0或(v[i]-v的最后一个元素等于0),则-
m[v[i]]:=i
如果ans与无穷大相同,则-
返回0
除此以外
返回的数字大小
让我们看下面的实现以更好地理解-
示例
#include <bits/stdc++.h> using namespace std; class Solution { public: int solve(vector<int>& nums, int k) { vector<int> v(nums.size() + 1, 0); int cnt = 0; for (int i = 0; i < nums.size(); ++i) { if (nums[i] < k) ++cnt; else if (nums[i] > k) --cnt; v[i + 1] = cnt; } if (v.back() == 0) return int(nums.size()); int delta = v.back(); map<int, int> m; int ans = INT_MAX; for (int i = 1; i <= v.size(); ++i) { if (m[v[i] - v.back()] != 0 || v[i] - v.back() == 0) { ans = min(ans, i - m[v[i] - v.back()]); } m[v[i]] = i; } if (ans == INT_MAX) return 0; else return int(nums.size() - ans); } }; main(){ Solution ob; vector<int> v = {6, 10, 8, 9, 3, 5}; int k = 6; cout << ob.solve(v, k); }
输入值
{6, 10, 8, 9, 3, 5}, 6
输出结果
5