Create Sorted Array through Instructions (H)
题目
Given an integer array instructions
, you are asked to create a sorted array from the elements in instructions
. You start with an empty container nums
. For each element from left to right in instructions
, insert it into nums
. The cost of each insertion is the minimum of the following:
- The number of elements currently in
nums
that are strictly less thaninstructions[i]
. - The number of elements currently in
nums
that are strictly greater thaninstructions[i]
.
For example, if inserting element 3
into nums = [1,2,3,5]
, the cost of insertion is min(2, 1)
(elements 1
and 2
are less than 3
, element 5
is greater than 3
) and nums
will become [1,2,3,3,5]
.
Return the total cost to insert all elements from instructions
into nums
. Since the answer may be large, return it modulo 109 + 7
Example 1:
Input: instructions = [1,5,6,2]
Output: 1
Explanation: Begin with nums = [].
Insert 1 with cost min(0, 0) = 0, now nums = [1].
Insert 5 with cost min(1, 0) = 0, now nums = [1,5].
Insert 6 with cost min(2, 0) = 0, now nums = [1,5,6].
Insert 2 with cost min(1, 2) = 1, now nums = [1,2,5,6].
The total cost is 0 + 0 + 0 + 1 = 1.
Example 2:
Input: instructions = [1,2,3,6,5,4]
Output: 3
Explanation: Begin with nums = [].
Insert 1 with cost min(0, 0) = 0, now nums = [1].
Insert 2 with cost min(1, 0) = 0, now nums = [1,2].
Insert 3 with cost min(2, 0) = 0, now nums = [1,2,3].
Insert 6 with cost min(3, 0) = 0, now nums = [1,2,3,6].
Insert 5 with cost min(3, 1) = 1, now nums = [1,2,3,5,6].
Insert 4 with cost min(3, 2) = 2, now nums = [1,2,3,4,5,6].
The total cost is 0 + 0 + 0 + 0 + 1 + 2 = 3.
Example 3:
Input: instructions = [1,3,3,3,2,4,2,1,2]
Output: 4
Explanation: Begin with nums = [].
Insert 1 with cost min(0, 0) = 0, now nums = [1].
Insert 3 with cost min(1, 0) = 0, now nums = [1,3].
Insert 3 with cost min(1, 0) = 0, now nums = [1,3,3].
Insert 3 with cost min(1, 0) = 0, now nums = [1,3,3,3].
Insert 2 with cost min(1, 3) = 1, now nums = [1,2,3,3,3].
Insert 4 with cost min(5, 0) = 0, now nums = [1,2,3,3,3,4].
Insert 2 with cost min(1, 4) = 1, now nums = [1,2,2,3,3,3,4].
Insert 1 with cost min(0, 6) = 0, now nums = [1,1,2,2,3,3,3,4].
Insert 2 with cost min(2, 4) = 2, now nums = [1,1,2,2,2,3,3,3,4].
The total cost is 0 + 0 + 0 + 0 + 1 + 0 + 1 + 0 + 2 = 4.
Constraints:
1 <= instructions.length <= 10^5
1 <= instructions[i] <= 10^5
题意
从左到右遍历一个数组,每次将当前元素x插入到新数组newArr中是新数组保持递增,且定义一次插入的花费是min(newArr中严格小于x的元素个数,newArr中严格大于x的元素个数)。问全部插入后的总花费。
思路
直接使用二分法去每次查找小于/大于x的个数会超时,原因在于插入到新数组的复杂度是(O(N)),总复杂度为(O(N^2))。
使用树状数组,单点修改+区间查询,tree[i]表示在已插入的元素中数字i出现的次数,每次遍历时查询小于/大于x的个数以及插入新元素的复杂度都为(O(logN)),总复杂度为(O(NlogN))。
代码实现
Java
class Solution {
public int createSortedArray(int[] instructions) {
int cost = 0;
int[] tree = new int[100001];
for (int i = 0; i < instructions.length; i++) {
int num = instructions[i];
int leftLen = sum(tree, num - 1);
int rightLen = i - sum(tree, num);
cost = (cost + Math.min(leftLen, rightLen)) % 1000000007;
add(tree, num, 1, 100000);
}
return cost;
}
private int lowbit(int x) {
return x & -x;
}
private void add(int[] tree, int index, int value, int max) {
while (index <= max) {
tree[index] += value;
index += lowbit(index);
}
}
private int sum(int[] tree, int index) {
int sum = 0;
while (index > 0) {
sum += tree[index];
index -= lowbit(index);
}
return sum;
}
}