每日一道算法:leetcode 刷题碰到的问题。
这是题目:
Given an unsorted array nums, reorder it such that nums[0] < nums[1] >nums[2] < nums[3]....
Example: (1) Given nums = [1, 5, 1, 1, 6, 4], one possible answer is
[1, 4, 1, 5, 1, 6]. (2) Given nums = [1, 3, 2, 2, 3, 1], one possible
answer is [2, 3, 1, 3, 1, 2].Note: You may assume all input has valid answer.
Follow Up: Can you do it in O(n) time and/or in-place with O(1) extraspace?
我的思路比较简单虽然通过了但是用了1081ms所以其实无论是时间复杂度还是空间复杂度都达不到要求,希望各位谁感兴趣的话试着用C做一下。下面是我的代码,如果有大神能帮我想到改进的方法也可以啊。(大体上是先快排之后然后再把后面一半的数插入前面一半的数):
void quicksort(int *nums, int numsSize);
void wiggleSort(int *nums, int numsSize){
quicksort(nums, numsSize);
int counter = 0;
int left = (numsSize - 1) / 2;
int right = numsSize - 1;
int cache[numsSize];
for(counter=1; counter <= numsSize; counter++){
if((counter & 1) == 1){
cache[counter - 1] = nums[left--];
}
else{
cache[counter - 1] = nums[right--];
}
}
for(counter=0; counter<numsSize; counter++){
nums[counter] = cache[counter];
}
}
void quicksort(int *nums, int numsSize){
if(numsSize <= 1){
return;
}
int left = 0;
int right = numsSize - 1;
int key = nums[left];
while(left < right){
while(nums[right] >= key && left < right){
right--;
}
nums[left] = nums[right];
while(left < right && nums[left] <= key){
left++;
}
nums[right] = nums[left];
}
nums[left] = key;
quicksort(nums, left);
quicksort(nums+left+1, numsSize - 1 - left);
}
另外在网上看到有些人的思路是先找出中指点(据说只需要O(n)的时间复杂度,我不知道为什么只要O(n)的时间复杂度就能找到中指点,希望有知道的大神顺便也帮我解释一下)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
排序
和插入
每个都很耗时,所以你的方法是非常低效的。我说一下我的思路。首先,题目说了给的输入是肯定有解的,所以就不需要考虑无解的情况了。由这一前提,我们可以遍历数组,交换数组中适当的项来达到目的。具体步骤为:
初始化2个索引:
n1=0,n2=1
用这两个索引由前至后遍历数组,判断当前元素是否满足规则(即元素按照大于和小于的顺序交替出现)
当不满足规则时,分情况讨论:
注意:
插入必须是成对的,因此,如果最后的元素个数为奇数时,
n1
处的元素不需要动,只需交换n2
及其后面的偶数个元素即可。反之,如果最后的元素个数为偶数,那么n1
处的元素也需要参与交换。这种方法是否一定能找到一个解?答案是肯定的,因为最后的m个相同的数的数量必然不大于全部元素个数的一半,否则原本就是无解的。即使最坏的情况,我们也能找到足够多的位置插入这些元素。
该算法时间复杂度接近
O(n)
(理想情况只需遍历一遍,最坏情况需要插入n/2
个元素,每次插入都需要移动一部分数组元素),空间复杂度O(1)
(除几个索引之外不需要额外存储空间)更新:
刚才又仔细思考了一下,发现根本不需要插入操作,只需要交换即可。上面的整个(3.2)步骤可以修改为: