144. 交错正负数
给出一个含有正整数和负整数的数组,重新排列成一个正负数交错的数组。
样例
给出数组[-1, -2, -3, 4, 5, 6]
,重新排序之后,变成[-1, 5, -2, 4, -3, 6]
或者其他任何满足要求的答案
挑战
完成题目,且不消耗额外的空间。
注意事项
不需要保持正整数或者负整数原来的顺序。
这道题目比较难,使用O(N)的算法来做的时候使用双指针,奇数偶数指标交替向后走的方法。
注意,题目输入保证了当n为偶数的时候,正数和负数个数是完全相同的。
当n为奇数的时候,正数个数只会比负数个数多1
所以这里要特别处理正数和负数个数的情况
时间复杂度为O(N), 空间复杂度O(N)。 不改变数组的顺序
class Solution {
public:
/*
* @param A: An integer array.
* @return: nothing
*/
void rerange(vector<int> &A) {
// write your code here
vector<int> postive;
vector<int> nagetive;
for(auto a:A){
if(a>=0) postive.push_back(a);
else nagetive.push_back(a);
}
int i=0,j=0,k=0;
// 如果正数个数大于负数的情况
if(postive.size()>nagetive.size()){
while(i!=postive.size() && j!=nagetive.size()){
A[k++] = postive[i++];
A[k++] = nagetive[j++];
}
while(i!=postive.size()) A[k++] = postive[i++];
}
// 如果负数个数大于正数的情况
else{
while(i!=postive.size() && j!=nagetive.size()){
A[k++] = nagetive[j++];
A[k++] = postive[i++];
}
while(j!=nagetive.size())A[k++] = nagetive[j++];
}
}
};
双指针做法
注意同样要判断两种情况, 时间复杂度为O(N), 这个做法会改变
class Solution {
public:
/*
* @param A: An integer array.
* @return: nothing
*/
void rerange(vector<int> &A) {
int posNum = 0;
int negNum = 0;
for(int i : A){
if(i > 0)
posNum++;
else
negNum++;
}
if(posNum>=negNum){
// 偶数下标放正数, 奇数下标放负数
for(int i=0;i<A.size();i++){
if(i%2==0 && A[i]>0) continue;
else if(i%2==1 && A[i]<0) continue;
else if(i%2==0 && A[i]<0){
int j=i+1;
while(j<A.size() && A[j]<0) j++; // 找到第一个A[j]>0的位置
if(j==A.size()) break;
swap(A[i],A[j]);
}
else if(i%2==1 && A[i]>0){
int j=i+1;
while(j<A.size() && A[j]>0) j++; // 找到第一个A[j]<0的位置
if(j==A.size()) break;
swap(A[i],A[j]);
}
}
}
else{
// 偶数下标放负数, 奇数下标放正数
for(int i=0;i<A.size();i++){
if(i%2==0 && A[i]<0) continue;
else if(i%2==1 && A[i]>0) continue;
else if(i%2==0 && A[i]>0){
int j=i+1;
while(j<A.size() && A[j]>0) j++; // 找到第一个A[j]>0的位置
if(j==A.size()) break;
swap(A[i],A[j]);
}
else if(i%2==1 && A[i]<0){
int j=i+1;
while(j<A.size() && A[j]<0) j++; // 找到第一个A[j]<0的位置
if(j==A.size()) break;
swap(A[i],A[j]);
}
}
}
}
};
如果不改变相对顺序
class Solution {
public:
/*
* @param A: An integer array.
* @return: nothing
*/
void rerange(vector<int> &A) {
int posNum = 0;
int negNum = 0;
for(int i : A){
if(i > 0)
posNum++;
else
negNum++;
}
if(posNum>=negNum){
// 偶数下标放正数, 奇数下标放负数
for(int i=0;i<A.size();i++){
if(i%2==0 && A[i]>0) continue;
else if(i%2==1 && A[i]<0) continue;
else if(i%2==0 && A[i]<0){
int j=i+1;
while(j<A.size() && A[j]<0) j++; // 找到第一个A[j]>0的位置
if(j==A.size()) break;
//swap(A[i],A[j]); // 如果要不改变位置,不能交换, 只能一位一位的移动
int temp = A[j];
for(int k=j-1;k>=i;k--){
A[k+1] = A[k];
}
A[i] = temp;
}
else if(i%2==1 && A[i]>0){
int j=i+1;
while(j<A.size() && A[j]>0) j++; // 找到第一个A[j]<0的位置
if(j==A.size()) break;
//swap(A[i],A[j]);
int temp = A[j];
for(int k=j-1;k>=i;k--){
A[k+1] = A[k];
}
A[i] = temp;
}
}
}
else{
// 偶数下标放负数, 奇数下标放正数
for(int i=0;i<A.size();i++){
if(i%2==0 && A[i]<0) continue;
else if(i%2==1 && A[i]>0) continue;
else if(i%2==0 && A[i]>0){
int j=i+1;
while(j<A.size() && A[j]>0) j++; // 找到第一个A[j]>0的位置
if(j==A.size()) break;
//swap(A[i],A[j]);
int temp = A[j];
for(int k=j-1;k>=i;k--){
A[k+1] = A[k];
}
A[i] = temp;
}
else if(i%2==1 && A[i]<0){
int j=i+1;
while(j<A.size() && A[j]<0) j++; // 找到第一个A[j]<0的位置
if(j==A.size()) break;
//swap(A[i],A[j]);
int temp = A[j];
for(int k=j-1;k>=i;k--){
A[k+1] = A[k];
}
A[i] = temp;
}
}
}
}
};