问题描述:给定一个整数数组和一个整数x,将数组中元素值为x的元素都放到数组的前面,其他元素的相对顺次不变。
例如:原数组为{4,0,1,0,2,,3,6,0,5},x=0,则调整后的数组为{0,0,0,4,1,2,3,6,5}
分析:该问题存在多种解法。
解法一:辅助数组法。创建一个和原数组一样长度的数组,从原数组的尾部开始扫描,如果元素值是x,则忽略。
否则,将元素拷贝到新数组的末尾。扫描完原数组后,再在新数组未重新赋值的元素全部赋值为x。
最后再将新数组的所有元素赋值到原数组中。
假设原数组的长度为n,则算法的空间复杂度为O(n),时间复杂度为O(n).
解法二:和解法一有点类似,设置一个指针 j 用来存储元素值为x的下标,初始设置j为数组最后元素的下标,然后从尾部开始扫描,
如果元素不是x,如果j所指元素为x,则交换两个元素的值,最后j--,如果元素是x,则忽略本次循环。
该方法不需要额外的辅助空间,空间复杂度为O(1),时间复杂度为O(n).
由于解法一比较简单,我就不再写具体的代码了,这里我给出解法二的Java代码实现。
import java.util.*;
public class Main{
public static void adjust(int a[],int x){
int i,j=a.length-1; //j为元素值为x的下标
for(i=a.length-1;i>=0;i--)
{
if(a[i]!=x)
{
if(a[j]==x)
{
int t=a[i]; //交换两个元素的位置
a[i]=a[j];
a[j]=t;
}
j--;
}
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner scan=new Scanner(System.in);
int a[]={4,0,1,0,2,3,6,0,5};
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+",");
}
System.out.println();
System.out.print("请输入要提前的元素值:");
int x=scan.nextInt();
adjust(a,x);
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+",");
}
}
}
测试样例输出为:
4,0,1,0,2,3,6,0,5,
请输入要提前的元素值:0
0,0,0,4,1,2,3,6,5,
举一反三:该题目是前移,同样会有后移,读者可以自己尝试编程实现。