给出n * n个元素的二维数组:
例如:
1 5 7
2 6 8
3 9 10
将其转换为1-D排序数组。是否有比O(nlog(n))
更好的解决方案。
答案 0 :(得分:1)
它的复杂程度可能低于n^2
,因为您有n^2
个元素,您必须至少每次检查一次。
执行此操作的算法是标准k-way合并,其复杂度为N log k
,其中N
是要合并的项目总数,k
为序列数。
在n*n
数组中,您要合并n*n
项和n
个序列(即行)。所以,用上面的等式代替:
N log k
N = (n*n)
k = n
(n*n) log n
将2D数组转换为已排序的1D数组n^2 log n
。
答案 1 :(得分:0)
您可以使用函数f(x,y)=(f(x),f(y))来降低复杂性并使2d数组变平。它还重新排序1d阵列。既然它是一个函数,它更像是一个散列算法,也许不是你想要的东西?
答案 2 :(得分:0)
你应该发布你的O(n log n)
解决方案:事实是,没有真正可行的解决方案。这就是原因。您有n*n
个元素。因此,您必须做的最好的事情是n^2
,因为您必须至少访问一次每个元素。考虑一下。您必须填充长度为n*n
的1-D数组(即2-D数组的每个元素必须存在于新的1-D数组中)。因此,您无法在O(n log n)
中解决此问题。
答案 3 :(得分:0)
我有时间:O(n * n log(2n))空间O(2n)算法。
基本思路如下
a [0] [0]肯定是最小的元素。因为元素是行方式和列方式排序的,所以下一个最小元素将是min(a [0] [1],a [1] [0])。比如,[0] [1]是两者中最小的,下一个候选者将是min(a [0] [2],a [1] [1],a [1] [0])
等等,
<强> ALGO:强>
选择最小的候选元素,打印出来。将元素推到最小元素的右侧和底部作为潜在候选者。 (检查出来或绑定。) 这样做直到不再存在候选元素。
需要DS:
候选元素可以使用堆维护(top是min元素)但是你需要确保你不要将同一个元素推两次。 (y可以是x的右边和z的底部)。 在你推送堆之前你需要知道元素是否已被推送。
这两个要求都由set(有序)(我用c ++编写代码)
优雅地处理在集合中存储索引将允许我轻松地将下一个候选元素推送到候选Ds 在我的候选人ds中,我在任何时间点都保持不超过n + n个元素 以下是我使用的比较功能。
bool operator()(const int& a,const int& b) const{
int ai=a/m,aj=a%m;
int bi=b/m,bj=b%m;
if(input[ai][aj]!=input[bi][bj])
return input[ai][aj]<input[bi][bj];
else
return a<b;
}
示例实现位于:http://ideone.com/w208Af
答案 4 :(得分:0)
你可以在O(n)中做到这一点。我不同意这是不可能比n ^ 2更快,因为在这种情况下n * n = n因为当你谈论时间复杂性时你指的是列表中的元素数量。这是O(n)解,其中n = min-max。为此,您需要知道列表中可能包含的最小数字和最大数字。你不需要知道它们是最低和最高的。
int[] Sorted1dArray(int[][] arr, int min, int max)//basically counting sort
{
int index = 0;
int rowColSize = arr[0].Length;
int[] newArr = new int[max-min];
int[] ret = new int[rowColSize *rowColSize ];
for(int i=0;i<rowColSize ;i++)//
{
for(int j=0;j<rowColSize ;j++)
newArr[arr[i][j]]++;
}
for(int i=0;i<newArr.Length;i++)
{
for(int j=0;j<newArr[i];j++)
{
ret[index++]=newArr[j];
}
}
return ret;
}
答案 5 :(得分:0)
我认为这将是我采取的方法:
1)从第一行开始 - “1 5 7”。我们知道在开始时,行是排序的,因此我们保证最左边的元素是最少的,不需要比较。输出1,然后将第一列向上移动,给我们“2 5 7”。
2)现在比较前两个元素。只要第一个元素小于第二个元素,就保持输出第一个元素并将其各自的列向上移动。这给了我们输出 2和3的结果数组为“5 7”(因为第一列现在为空)。
3)继续对剩余的两个colums做同样的事情。在我们遇到第一个不同的情况之前,这将给出5和6的输出 - 此时我们的数组将包含“9 7”。
4)在这种情况下,我们将从最后一列输出值并将其向上移动,在输出7后给出“9 8”。我们再次得到第一个元素更大的情况,所以我们'输出第二个并将该列向上移动,留下“9 10”。
没有彻底分析它,但我认为这是O(N),因为你可以对各个列之间的关系做出假设,因此最多有N个比较。