锯齿形数组

starboy520 2010-04-27 05:21:09
给定一个N个整数元素的数组,元素分别为A1, A2, A3....AN, 将数组变为A1 < A2 > A3 < A4.....的锯齿状数组;时间复杂度

有比O(nlog(n)) 好的算法吗
...全文
1089 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyfhz 2010-04-30
  • 打赏
  • 举报
回复
对,我现在就是在想已知N个不同的值和这N个值出现的次数,有没有好的办法判定出它们是否可以构成锯齿数组。
chenchangxiong 2010-04-30
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 yyfhz 的回复:]
引用 16 楼 chenchangxiong 的回复:
引用 15 楼 yyfhz 的回复:
如果允许出现相同的数字,情况会变得复杂了。很明显的一点是:如果某一数字重复次数>(N+1)/2 (向下取整),则不可能构成标准的锯齿形数组。
接下来的问题是判定一个可重复序列是否可以构成一个锯齿形数组,还没想明白,难道只有用遍历+回溯的办法一个一个来测试?

这个到不用,因为很容易证明,如果出现……
[/Quote]
是的,这是判断是否存在的一种方式。我写错了,应当是不允许存在相邻数相等的情况,中位数的查找是必要的,然后一个动作是对等于中位数的数根据所在集合向两边调整,这样能满足要求。
我不知道这个问题的具体下限是,但是若存在,上面的肯定能找到一个满足要求的数列;若不存在,在可以通过中位数的个数是否超过半数判定。
yyfhz 2010-04-30
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 chenchangxiong 的回复:]
引用 15 楼 yyfhz 的回复:
如果允许出现相同的数字,情况会变得复杂了。很明显的一点是:如果某一数字重复次数>(N+1)/2 (向下取整),则不可能构成标准的锯齿形数组。
接下来的问题是判定一个可重复序列是否可以构成一个锯齿形数组,还没想明白,难道只有用遍历+回溯的办法一个一个来测试?

这个到不用,因为很容易证明,如果出现某一数字重复次数>(N+1)/2,那么这个数就是中位数,所……
[/Quote]
应该不会吧?某一数字重复次数>(N+1)/2,那么这个数就是中位数。
这个当然没错,但是同时根据抽屉原理,不论采用何种排列方式,都不可能将这个中位数的各个元素完全隔离,至少有两个中位数会黏在一起,这样就不能符合严格的锯齿形数组的定义了。
chenchangxiong 2010-04-30
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 yyfhz 的回复:]
如果允许出现相同的数字,情况会变得复杂了。很明显的一点是:如果某一数字重复次数>(N+1)/2 (向下取整),则不可能构成标准的锯齿形数组。
接下来的问题是判定一个可重复序列是否可以构成一个锯齿形数组,还没想明白,难道只有用遍历+回溯的办法一个一个来测试?
[/Quote]
这个到不用,因为很容易证明,如果出现某一数字重复次数>(N+1)/2,那么这个数就是中位数,所以对以中位数为基准的大小两个集合中对和中位数相同的数进行向不同方向的两端调整得到的数,肯定满足要求
yyfhz 2010-04-29
  • 打赏
  • 举报
回复
如果允许出现相同的数字,情况会变得复杂了。很明显的一点是:如果某一数字重复次数>(N+1)/2 (向下取整),则不可能构成标准的锯齿形数组。
接下来的问题是判定一个可重复序列是否可以构成一个锯齿形数组,还没想明白,难道只有用遍历+回溯的办法一个一个来测试?
LeonTown 2010-04-28
  • 打赏
  • 举报
回复
赞!
似乎都不需要找中位数了。

[Quote=引用 11 楼 chenchangxiong 的回复:]
可以证明,如果不存在相同元素,直接在数组上操作,一次扫描可以满足要求,算法证明如下:
设数组为A1,A2,.....An
则如果A1 < A2, 那么A1, A2满足条件
假设A1,A2,....Ai满足条件
若下面的操作符为<,那么前面的操作符必为>,即有Ai-1 > Ai
如果,Ai < Ai+1, 那么A1, A2, ... Ai-1, Ai, Ai+1满足条件
如果,Ai > ……
[/Quote]
michael122 2010-04-28
  • 打赏
  • 举报
回复
ls的方法很不错,mark
chenchangxiong 2010-04-28
  • 打赏
  • 举报
回复
可以证明,如果不存在相同元素,直接在数组上操作,一次扫描可以满足要求,算法证明如下:
设数组为A1,A2,.....An
则如果A1 < A2, 那么A1, A2满足条件
假设A1,A2,....Ai满足条件
若下面的操作符为<,那么前面的操作符必为>,即有Ai-1 > Ai
如果,Ai < Ai+1, 那么A1, A2, ... Ai-1, Ai, Ai+1满足条件
如果,Ai > Ai+1, 那么,调换Ai与Ai+1的位置,得到A1, A2, ....Ai-1, Ai+1, Ai
由Ai-1 > Ai > Ai+1,所以,满足要求。
同理,若操作符为>, 那么同样的换位操作也能满足要求。
所以,A1,A2,....An,可以通过上面的操作,变成锯齿形数组。
michael122 2010-04-28
  • 打赏
  • 举报
回复
查找任意第k大元素最坏情况都是O(n),lz看一下算法导论
chenchangxiong 2010-04-28
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 leontown 的回复:]
赞!
似乎都不需要找中位数了。


引用 11 楼 chenchangxiong 的回复:
可以证明,如果不存在相同元素,直接在数组上操作,一次扫描可以满足要求,算法证明如下:
设数组为A1,A2,.....An
则如果A1 < A2, 那么A1, A2满足条件
假设A1,A2,....Ai满足条件
若下面的操作符为<,那么前面的操作符必为>,即有Ai-1 > Ai
如果,Ai……
[/Quote]
这个只是在假定不存在相同元素的情况,还有如果存在相同元素的话,<改成<= >改成>=才行。
如果题目没做上面两者之一的限制,那么,还是得找中位数,只是对中位数相同的数进行特殊处理而已,比如把小于等于中位数的集合中,中位数提前,而大于的放后面
qq120848369 2010-04-27
  • 打赏
  • 举报
回复
LS,你的算法肯定达不到平均O(n),最坏O(n)更不可能. 但是的确有最坏情况的线性时间划分方法,算法书上一般都有,可以去了解一下.通过数学证明,对划分数的选择进行了具体的选择,而不是单纯的随机选择或者像你这样选择low元素去划分.
starboy520 2010-04-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 litaoye 的回复:]

可以O(n),用nth Element(就是类似快排的Partition)找到中位数O(n),然后把大于中位数的放在奇数下标,小于的放在偶数下标就可以了,也是O(n)
[/Quote]

请问下
这个所谓的 求第k大元素,是线性时间吗?

int split(int a[], int low, int high )
{
int i,j,x;
i=low;
x = a[low];
for(j=low+1;j<=high;j++)
{
if(a[j] <= x)
{
i++;
if( i != j)
{
int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
int tp1 = a[low];
a[low] = a[i];
a[i] = tp1;

return i;
}


int find_kth_max_number(int *a, int low ,int high, int k)
{
int m = split(a, low, high);
if ( m - low + 1 == k)
return a[m];
else
{
if(m - low + 1 > k)
find_kth_max_number(a, low, m, k);
else
find_kth_max_number(a, m+1, high, k-(m - low + 1) );
}
}

starboy520 2010-04-27
  • 打赏
  • 举报
回复
O(n)怎么求中位数
kenyyy 2010-04-27
  • 打赏
  • 举报
回复
好像是弄错了,A1 < A2 > A3 ,不一定A1 > A3 的。。。
绿色夹克衫 2010-04-27
  • 打赏
  • 举报
回复
发晚了,呵呵!
绿色夹克衫 2010-04-27
  • 打赏
  • 举报
回复
可以O(n),用nth Element(就是类似快排的Partition)找到中位数O(n),然后把大于中位数的放在奇数下标,小于的放在偶数下标就可以了,也是O(n)
michael122 2010-04-27
  • 打赏
  • 举报
回复
a_(n/2+1),...,a_n 都大于a
michael122 2010-04-27
  • 打赏
  • 举报
回复
可以达到O(n):
1. 用O(n)找到中位数a,把数组变成a_1,...,a_(n/2-1) 都小于a, a_(n/2+1),...,a_n 的样子,这也是O(n)
2. a_1<a_(n/2+1)>a_2<a_(n/2+2).... 即可,即把两半数组交叉就行了
kenyyy 2010-04-27
  • 打赏
  • 举报
回复
O(n)的应该没有,要是有,那排序的复杂度也可以变为O(n)了

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧