示例:A = [4,1,3,2,3,3]。然后我们得到B = [16,1,12,3,12,12]。
方法1:对于每个i,只需搜索A并总结小于或等于A [i]的数字。粗略地说,这需要横穿A n次,因此需要花费O(n ^ 2)时间。
方法2:排序A得到A',然后找到A'的cumsum。这需要横穿A'一次。所以整体运行时间就是排序,O(n log n)。
然而,当有关系时,这不起作用。对于上面的例子,我们得到A'= [1,2,3,3,3,6],所以cumsum(A')= [1,3,6,9,12,16],这是不一样的作为B(已排序)。
有没有办法解决这个问题,以便它仍然在O(n log n)中运行?
答案 0 :(得分:4)
使用现代语言的一种方法是使用词典:
A=random_integers(1,10,10)
SA=sorted(A) #O(n log n)
CSA=cumsum(SA) #O(n)
I=dict(zip(SA,CSA)) #O(n)
B=[I[x] for x in A] #O(n)
在构建字典时,遇到的最后一个值会替换现有的值,因此至少它适合好的值。 这给了:
[7 5 4 1 4 2 6 7 8 2]
[1 2 2 4 4 5 6 7 7 8]
[1 3 5 9 13 18 24 31 38 46]
{1:1, 2:5, 4:13, 5:18, 6:24, 7:38, 8:46}
[38 18 13 1 13 5 24 38 46 5]
答案 1 :(得分:2)
好的,如果你允许O(n log n)
那么这是一个非常简单的方法来实现它:
j
,使得A'[j]> = A_i, Ans [i ] = S [j] Ans 是您想要的数组
下面是一个示例C ++代码说明了这个想法
#include<bits/stdc++.h>
using namespace std;
int A[6] = {4, 1, 3, 2, 3, 3}, B[6], SUM[6] = {0}, ANS[6];
int main(){
for(int i=0; i<6; i++) B[i] = A[i];
sort(B, B+6);
for(int i=0; i<6; i++) SUM[i] = (i? SUM[i-1]:0) + B[i];
for(int i=0; i<6;i++){
int j = upper_bound(B,B+6, A[i]) - B;
ANS[i] = SUM[j-1];
printf("%d ", ANS[i]);
}
puts("");
return 0;
}
答案 2 :(得分:2)
更好的方法可能是将A排序为A'= [1,3,6,9,12,16],然后找到整数的总和而不是cumsum,迭代数组,如下所示:
B[A.length-1] = sum;
for(int i=A.length-2; i=0; i++){
if(A[i]!=A[i+1]){
B[i] = sum - B[i+1];
}
else{
B[i] = B[i+1];
}
}
答案 3 :(得分:1)
在排序方法中,在存储结果之前,找到具有相同值的所有元素(现在它们都是连续的,因此这与您已经进行过的遍历相同)并将它们一起处理:计算总和(对所有人都一样),然后记录每个人的(相同)结果。
答案 4 :(得分:1)
我很容易在o(nlogn)中这样做。
java.util.Arrays.sort(input, new java.util.Comparator<int[]>() {
public int compare(int[] a, int[] b) {
return Double.compare(a[1], b[1]);
}
});
这是我的java代码
class Solution
{
public static void main (String[] args) throws java.lang.Exception
{
int[][] input={{0,4}, {1,1}, {2,3}, {3,2}, {4,3}, {5,3
//sort one column with respect to other column in 2d array
java.util.Arrays.sort(input, new java.util.Comparator<int[]>() {
public int compare(int[] a, int[] b) {
return Double.compare(a[1], b[1]);
}
});
int[] temp=new int[6]; //Answer array
int sum=0;
for(int i=0;i<6;i++){
sum=sum+input[i][1];
}
int count=1;
temp[input[5][0]]=sum;
for(int i=4;i>=0;i--){
if(input[i][1]==input[i+1][1]){
count++;
temp[input[i][0]]=sum;
}
else{
sum=sum-(count*input[i+1][1]);
temp[input[i][0]]=sum;
count=1;
}
}
for(int i=0;i<6;i++)
System.out.print(temp[i]+" ");
}
}