我有一个N个元素的数组,只包含两个不同的键,true和false。我正在尝试编写一个O(N)算法来重新排列列表,以便所有虚假元素都在真正的元素之前。这个算法的一个特定要求是我只能遍历数组一次(这意味着我不能在数组上进行两次遍历;一次计算真/假的次数以及另一次将数值分配到数组中) 。我也不允许创建外部临时数组。
最初我想使用计数排序,但意识到我不能这样做,因为这个赋值的要求是我不能创建外部/临时数组。
然后,由于只有两个可能的值,我想迭代一次并计算它们。然后再次迭代并设置排序(进行排序)。但是,我不能这样做,因为我只允许进行一次迭代。
所以我自己尝试实现一种算法,该算法只能在数组中迭代一次并同时排序。到目前为止,我提出的是下面的内容(这只是一个或多或少写为伪代码的想法)
array = T T T T F F F F
int len = length of array.
counter = 0
For item in array
counter += 1
If counter <= len/2
if T change to F
else
if F change to T
当我完成此操作时,我意识到只有当所有T值都在数组的一侧时,这才有效,并且所有F值都在另一侧。
我的问题是,有人可以告诉我哪种O(n)排序算法可以用来对数组中的每个项进行排序并排列它以便所有的假元素都在真正的前面吗?
答案 0 :(得分:2)
您可以尝试快速排序的想法:同时从开始和结束遍历数组,并交换顺序不正确的元素。即如果您在数组的左半部分找到true
,请将其与右半部分的false
交换。
因为你只有2个不同的值就足够了。
示例:
bool[] array = ...;
int low = 0;
int high = array.Length - 1;
do
{
while (array[low] == false)
low++;
while (array[high] == true)
high--;
if (low <= high)
{
bool temp = array[low];
array[low] = array[high];
array[high] = temp;
}
}
while (low < high);
这给你完全一次通过,即O(N)。
答案 1 :(得分:1)
简明扼要:
swap = 0
for index in range(len(list)):
if list[index] != true:
list[index], list[swap] = list[swap], list[index]
swap += 1
答案 2 :(得分:1)
保持索引(lastFalseIdx
)插入False
元素的位置。因此,最初它是0.从左到右遍历数组,如果找到False
,则将其与lastFalseIdx
处的元素交换,并递增索引。
Python(几乎是伪代码):
arr = [True, True, False, False, False, True]
print arr
lastFalseIdx = 0
for idx, val in enumerate(arr):
if val == False:
arr[lastFalseIdx], arr[idx] = arr[idx], arr[lastFalseIdx] # swap elements
lastFalseIdx = lastFalseIdx + 1
print arr
答案 3 :(得分:1)
这是一个部分解决方案,它在单独的数组中构造正确的输出。您可以通过观察初始化output = input
时发生的情况来推断内联实现。
#!/usr/bin/python
input = [False, True, False, False, True, True, False, True, False]
def sort2(input):
i_false = 0
i_true = len(input) - 1
output = [None] * len(input)
for (i, val) in enumerate(input):
if val:
output[i_true] = True
i_true -= 1
else:
output[i_false] = False
i_false += 1
return output
print sort2(input)
在单个正向传递数组后,您将获得所需的输出。
答案 4 :(得分:0)
希望以下答案有所帮助。
internal void ArrangeBooleanArray()
{
bool[] inputArray = {false, true, true, false};
int arrayLength = inputArray.Length;
bool[] outputArray = new bool[arrayLength];
int trueCount = 0;
int falseCount = 0;
foreach (var item in inputArray)
{
if (item == true)
{
trueCount++;
outputArray[arrayLength - trueCount] = item;
}
else
{
outputArray[falseCount] = item;
falseCount++;
}
}
}