我是一名新程序员,我正在尝试按奇偶校验对整数向量进行排序-将偶数放在赔率前。奇数或偶数内部的顺序本身并不重要。例如,给定输入[3,1,2,4],输出可以是[2,4,3,1]或[4,2,1,3],等等。下面是我的c ++代码,有时我幸运的是,向量得到了正确的排序,有时却没有。我导出了奇数和偶数向量,它们看起来正确,但是当我尝试将它们组合在一起时,结果就一团糟。有人可以帮我调试吗?
class Solution {
public:
vector<int> sortArrayByParity(vector<int>& A) {
unordered_multiset<int> even;
unordered_multiset<int> odd;
vector<int> result(A.size());
for(int C:A)
{
if(C%2 == 0)
even.insert(C);
else
odd.insert(C);
}
merge(even.begin(),even.end(),odd.begin(),odd.end(),result.begin());
return result;
}
};
答案 0 :(得分:5)
如果您只需要在偶数前加上偶数而不是完整的排序,我建议您使用std::partition
。您给它两个迭代器和一个谓词。谓词返回true
的元素将出现在其他元素之前。它可以就地工作,并且应该非常快。
类似这样的东西:
std::vector<int> sortArrayByParity(std::vector<int>& A)
{
std::partition(A.begin(), A.end(), [](int value) { return value % 2 == 0; });
return A;
}
答案 1 :(得分:2)
因为merge
函数假定两个范围已排序,因此在合并排序中使用。相反,您应该只使用vector
的{{3}}函数:
result.insert(result.end(), even.begin(), even.end());
result.insert(result.end(), odd.begin(), odd.end());
return result;
答案 2 :(得分:2)
无需创建三个单独的向量。当您在结果向量中分配了足够的空间时,该向量可用作最终向量,还可以存储子向量,并存储分隔的奇数和偶数。
使用向量的价值是避免插入和移动,该向量在幕后是数组。数组/向量之所以快速,是因为它们允许从头开始的偏移量立即访问内存。利用这一点!
该代码只保留下一个奇数和偶数索引的索引,然后相应地分配正确的单元格。
class Solution {
public:
// As this function does not access any members, it can be made static
static std::vector<int> sortArrayByParity(std::vector<int>& A) {
std::vector<int> result(A.size());
uint even_index = 0;
uint odd_index = A.size()-1;
for(int element: A)
{
if(element%2 == 0)
result[even_index++] = element;
else
result[odd_index--] = element;
}
return result;
}
};
答案 3 :(得分:0)
利用您不关心偶数或奇数本身的顺序这一事实,您可以使用一种非常简单的算法对数组就地进行排序:
// Assume helper function is_even() and is_odd() are defined.
void sortArrayByParity(std::vector<int>& A)
{
int i = 0; // scanning from beginning
int j = A.size()-1; // scanning from end
do {
while (i < j && is_even(A[i])) ++i; // A[i] is an even at the front
while (i < j && is_odd(A[j])) --j; // A[j] is an odd at the back
if (i >= j) break;
// Now A[i] must be an odd number in front of an even number A[j]
std::swap(A[i], A[j]);
++i;
--j;
} while (true);
}
请注意,上述函数返回void,因为向量是按原位排序 的。如果确实要返回输入向量的排序后的副本,则需要在函数内定义一个新向量,并在每个++i
和{{1}之前复制元素}(当然也不要使用--j
,而是横向复制元素;也请以std::swap
的形式传递A
)。
const std::vector<int>& A
在上述两种情况下(原地为 或原地),该函数的复杂度为O(N),N为{{ 1}},比一般的O(N log N)对N个元素进行排序要好得多。这是因为问题实际上并没有 sort 太多-它只会将奇数与偶数分开。因此,无需调用完整的排序算法。