给定一组正数和负数(没有零),我必须以正数和负数应该连续排列的方式来排列它们。
正数和负数的数目可能不相等,即如果没有剩余的正数(或负数),则所有剩余的负数(或正数)将附加到数组的末尾。
顺序很重要,即如果输入数组是{2,-1,-3,-7,-8, 9, 5,-5,-7}
,那么输出数组应该是m1in1o1p。代码在O(n)中完成,而不使用其他数组。
这是我用java编写的解决方案,我在几个案例中再次测试了它,它可以工作。然而,我不确定这次运行是否需要O(n)时间。基本上,我先数正数和负数。然后我有两个索引i = 0
和j =1
。j
总是比i
提前1步。从这里我继续检查i
中的数字是否为正,j
是否为负,如果不是,m1on8o1p将遍历数组,直到找到正确位置的下一个正/负,并将其移动到正确位置。
任何建议都非常感谢。谢谢
//array of negative and positive, arrange them so that positive number follow by negative
// if no pos or neg left, the rest append to the array.
//should be O(n) no additional array
public static void alter(int[] a) {
int pos = 0;
int neg = 0;
int index = 0;
while (c < a.length) {
if (a[index] > 0) {
pos++;
} else neg++;
index++;
}
int i = 0;
int j = 1;
int temp = 0;
//run until no more positive number or negative number
while (pos > 0 && neg > 0) {
//
if (a[i] > 0) {
pos--;
if (a[j] < 0) {
i += 2;
j += 2;
neg--;
} else // a[j] > 0
{
while (a[j] > 0) {
j++;
}
//a[j] < 0
neg--;
//move that number to the appropriate place
while (j > i) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
j--;
} // end while
i += 2;
j += 2;
}
} else // a[i] < 0
{
while (a[i] < 0) {
i++;
}
//a[i] > 0
//move that number to the appropriate place
while (i > (j - 1)) {
temp = a[i];
a[i] = a[i - 1];
a[i - 1] = temp;
i--;
}
} //end else
}
}
3条答案
按热度按时间4bbkushb1#
但是,我不确定这次运行是否在
O(n)
时间内我认为它不是在
O(n)
中运行的。当您必须“找到下一个正确的元素并将其移动到正确的位置”时,您需要1.循环处理数组的其余部分。这意味着在最坏的情况下(数组的开头是所有正元素,结尾是所有负元素),您将在数组“未排序”部分的一半以上为每个正元素再循环一次
1.将元素移回正确位置时,会逐位置移动它。这意味着您将再次在数组的“未排序”部分上循环
如果需要遵守不使用第三个数组就必须遵守顺序的要求,那么还不确定如何在
O(n)
中运行它。iyr7buue2#
可以,可以在O(n)中完成。
假设c是当前位置。a[c]是正数。
1) 从c向数组末尾递增i,直到i指向第一个错误的数字(与前面的符号相同的数字,在本例中为正数)。
2)
Set j := i
;3) 向数组末尾递增j,直到j指向带所需符号的数字(在本例中为负数)。
4)
Swap a[i] with a[j]
页。5)
Set c := j
;6)
Set j := c + 1
;在每个步骤中,您总是递增i或j或c****永远不要减量。变量i的增量不能超过n次。与j和c相同。
因此,最大增量数为3n~O(n)。
sc4hvdpw3#
PFB我的代码。如果我们使用Stack,那么它将使我们的问题更容易解决。
}