我开始习惯算法,我需要帮助解决这类问题。
任务集:
数组以随机顺序包含绵羊和山羊。写一个可能的 重新排列阵列的快速方法,以便所有山羊都在 开始,所有的羊都在阵列的末尾。考虑这个案子 当所有的动物都是同一种动物时。
public class Sheep {
enum Animal {sheep, goat};
public static void main (String[] param) {
// for debugging
}
public static void reorder (Animal[] animals) {
// TODO!!! Your program here
}
}
感谢您的帮助!
答案 0 :(得分:1)
使用两个指针,一个从头开始,另一个在结尾。
增加开始指针,直到它位于绵羊上或遇到结束指针。 减少结束直到它放在山羊上或遇到开始指针。 在两个指针处交换条目。 重复直到指针相遇。
这是O(n),不需要额外的空间。
它本质上是快速排序算法的分区过程。
答案 1 :(得分:0)
如果绵羊或山羊的顺序不重要,那么任何排序算法都会慢于单一通过算法,只会在列表的两端粘住绵羊和山羊。
这样的一个例子就是双端队列或dequeue
:
一些伪代码:
Dequeue<animal> myQ;
for(int i = 0; i < animalList.length; i++){
if(animalList[i].name == "goat") myQ.push_front(animalList[i]);
else myQ.push_back(animalList[i]);
}
此算法因此O(n)
使用O(n) extra space
,而不是使用O(nlog(n))
额外空格排序O(n)
即合并排序或O(n^2)
快速排序(摊销{{ 1}})
这也可以使用O(nlog(n))
swapping
来完成。如果前面是与后面的羊交换(如果它是山羊),则从前面和后面运行列表,即:
O(n) and no extra space
答案 2 :(得分:0)
这是类似于快速排序的算法,但在你的情况下,它会在O(n)时间结束。
你从两边走,直到你发现两边都是坏动物。然后你切换它们并继续。
public static void reorder (Animal[] animals) {
int j = animals.length - 1;
int i = 0;
while (i < j){
if (animals[i] == Animal.goat){
i++;
} else if (animals[j] == Animal.sheep){
j--;
} else {
Animal temp = animals[i];
animals[i] = animals[j];
animals[j] = temp;
}
}
return animals;
}
答案 3 :(得分:0)
你真正需要的是快速排序算法的一次迭代。它被称为分区。 C ++标准库提供了实现link。