对于有一个排好序的数组,它的元素可以从队首或者队尾加入或弹出,即双端队列。
每当我们需要插入一个元素,并且保持它是排好序的,可以选择做两种操作
从队首或队尾弹出一个元素。
将待插入元素加入到队首或队尾。
将之前弹出的元素重新加入到队首或队尾。
每插入一个元素后要保持队列是递增的。
现在给你一个待插入元素的数组,请按顺序插入到一个空数组中,并计算出最少操作次数。
待插入的数组 numsnumsnums 的长度为 nnn,1≤n≤1051 \le n \le 10^51≤n≤105.
数组中的每个数字各不相同,1≤numi≤n1 \le num_i \le n1≤numi≤n。
样例中,最少需要 666 步:
将 111 放入队尾。
将 333 放入队尾。
将 444 放入队尾。
将 111 从队首取出。
将 222 放入队首。
将 111 放入队首。
样例
输入:
[1,3,4,2]
输出:
6
struct Tree
{
int start, end, count;
Tree **child;
Tree(int a, int b, int c)
{
start = a;
end = b;
count = c;
child = nullptr;
}
};
Tree* create(int start, int end, int n)
{
Tree * root = nullptr;
if (start == end)
{
root = new Tree(start,end,0);
return root;
}
root = new Tree(start, end, 0);
root->child = (Tree**)malloc(sizeof(Tree*) * n);
int num = (end - start) / n;
int index = start;
Tree *node = nullptr;
for (int i = 0; i < n; i++)
{
if (index + num > end)
{
root->child[i] = create(index, end, n);
break;
}
node = create(index, index + num, n);
root->child[i] = node;
index += num + 1;
if (index > end)
{
break;
}
}
return root;
}
void adjustTreeCount(Tree* root, int num,int n)
{
if (nullptr == root)
{
return;
}
if (num > root->end )
{
return;
}
if ((num == root->start) && (num == root->end))
{
root->count++;
return;
}
Tree *node = nullptr;
for (int i = 0; i < n; i++)
{
node = root->child[i];
if (nullptr == node)
{
return;
}
if (num > node->end)
{
continue;
}
if (num < node->start)
{
return;
}
adjustTreeCount(node, num, n);
root->count++;
return;
}
}
long long sumTreeCount(Tree* root, int num, int n)
{
if (nullptr == root)
{
return 0;
}
if (num >= root->end)
{
return root->count;
}
if (num < root->start)
{
return 0;
}
long long ret = 0;
Tree *node = nullptr;
for (int i = 0; i < n; i++)
{
node = root->child[i];
if (num >= node->end)
{
ret += node->count;
}
else if (num >= node->start)
{
ret += sumTreeCount(node, num, n);
}
else if (num < node->start)
{
break;
}
}
return ret;
}
long long sortedArrangement6(vector<int> &nums) {
long long count = 0;
int n = 10;
Tree* root = create(0, 100000, n);
for (int i = 0; i < nums.size(); i++)
{
int left = sumTreeCount(root, nums[i],n);
int right = i - left;
count += 2 * min(left, right) + 1;
adjustTreeCount(root, nums[i], n);
}
return count;
}