解法一:辅助数组法。创建一个和原数组一样长度的数组,从原数组的尾部开始扫描,如果元素值是x,则忽略。
否则,将元素拷贝到新数组的末尾。扫描完原数组后,再在新数组未重新赋值的元素全部赋值为x。
最后再将新数组的所有元素赋值到原数组中。
假设原数组的长度为n,则算法的空间复杂度为O(n),时间复杂度为O(n).
解法二:和解法一有点类似,设置一个指针 j 用来存储元素值为x的下标,初始设置j为数组最后元素的下标,然后从尾部开始扫描,
如果元素不是x,如果j所指元素为x,则交换两个元素的值,最后j--,如果元素是x,则忽略本次循环。
该方法不需要额外的辅助空间,空间复杂度为O(1),时间复杂度为O(n).
/*
问题描述:给定一个整数数组和一个整数x,将数组中元素值为x的元素都放到数组的前面,其他元素的相对顺次不变。
例如:原数组为{ 4, 0, 1, 0, 2, , 3, 6, 0, 5 },x = 0,则调整后的数组为{ 0, 0, 0, 4, 1, 2, 3, 6, 5 }
*/
void adjust_data(vector<int> data, int T)
{
//将指定的元素T 放在前面
//从末尾开始,一个index_j 指定T的位置(最右边的T),一个index指向index_j左边非T元素的位置,两者交换
//不断左移动交换,直到最左边的元素交换完
int j = data.size() - 1;
int i = data.size() - 1;
while (i >= 0)
{
if (data[i] != T)//i一直到移动不是T的数据为止
{
//如果data[i] 不等于T,而data[j]等于T,则可以交换
if (data[j] == T)
{
int tmp = data[j];
data[j] = data[i];
data[i] = tmp;
}
//i不是T时,j也移动一步
j--;//交换之后,需要左移;同样的,j此时如果指的不是T,也需要左移
}
//交换之后,i需要左移;没有交换也需要左移
//如果i指定的元素是T,则i继续左移,一直找到非T元素的位置(往左走的第一个非T)
i--;//继续往左移
}
for (int i = 0; i < data.size(); i++)
{
cout << data[i] << " ";
}
cout << endl;
}
int num_data2[10] = { 1, 3, 2, 3, 4, 3, 6, 8, 3, 0 };
vector<int> new_data2(num_data2, num_data2 + 10);
adjust_data(new_data2, 3);