我们不能使用多个DS。 时间复杂度O(n)。
目标:左侧的所有负面元素和右侧的正面元素。
请不要排序。
我正在尝试这个,但不知道这里有什么问题。
请帮帮忙!
我很确定所有案件都会得到照顾!
#include <iostream>
using namespace std;
int main(void){
int arr[100], n, temp=0;
cout << "Enter the size of array";
cin >> n;
for(int i=0; i<n; i++){
cout << "Enter elements of array";
cin >> arr[i];
}
int j=0;
for(int k=n-1; k>=j; k--) {
if(arr[j]<0 && arr[k]>=0) {
j++;
}
if(arr[j]>=0 && arr[k]<0) {
temp = arr[k];
arr[k] = arr[j];
arr[j] = temp;
j++;
}
if(arr[j]<0 && arr[k]<0) {
j++;
k++;
}
if(arr[j]>=0 && arr[k]>=0) {
continue;
}
}
cout << arr;
}
答案 0 :(得分:1)
你不能用零做出你想做的事情;假设零被忽略,它们的位置并不重要。如果零被视为正面或负面,或者它们应该出现在中间而不是任意位置,下面的一些细节将需要调整,但这将使你基本上得到你想去的地方。
i
称为。如果未找到正数,则终止算法。j
称为。如果未找到负数,则终止算法。i < j
,交换索引i
和j
的元素,并递归地解决从i+1
到j-1
的数组切片的相同问题,包含(如果i+1 >= j-1
,您可以简单地终止)。这可以保证正确解决您的问题。证明是通过对数组长度的数学归纳。
基本情况:空数组和长度为1的数组已经满足所需的属性,不需要交换。该算法会查看此类数组,并且不执行任何操作。
归纳假设:假设算法正确处理了最多k
个元素的所有数组;也就是说,算法将所有负元素向左移动,所有正元素向右移动。
归纳步骤:我们必须证明算法正确处理长度为k+1
的数组。假设k+1
元素数组已满足该属性。我们的算法查看所有元素并且什么都不做。相反,假设至少有一个元素不合适。这意味着有一个正数,右边有一个负数。特别是,在其右侧有一个最左边的正数,负数。同样,最右边的负数在其左边有一个正数。我们的算法交换这两个数字,创建一个数组,这些数字不再是不合适的。由于我们假设最左边和最右边的正数和负数,任何其他掉期必须出现在我们刚刚交换的数字内。我们的算法处理数组的这一部分,其大小最多为k+1-2 = k-1
,根据假设,我们的算法正确处理。 QED
迭代实现的伪代码:
i = 0
j = n-1
while i < j do
while !(array[i] > 0) do
i = i + 1
while !(array[j] < 0) do
j = j - 1
if i < j then
tmp = array[i]
array[i] = array[j]
array[j] = tmp
如果您想将零视为否定,请将array[j] < 0
更改为array[j] <= 0
。如果您想将零视为正数,请将array[i] > 0
更改为array[i] >= 0
。如果你想在中间使用零,那么运行上面的伪代码三次:一次交换负数和正数,一次交换负数和零,一次交换正数和零。