数组元素前移问题(今日头条笔试题)
问题描述:给定一个整数数组和一个整数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代码实现。
1 import java.util.*; 2 public class Main { 3 public static void adjust(int a[],int x){ 4 int i,j=a.length-1; //j为元素值为x的下标 5 for(i=a.length-1;i>=0;i--) 6 { 7 if(a[i]!=x) 8 { 9 if(a[j]==x) 10 { 11 int t=a[i]; //交换两个元素的位置 12 a[i]=a[j]; 13 a[j]=t; 14 } 15 j--; 16 } 17 } 18 } 19 20 public static void main(String[] args) { 21 // TODO 自动生成的方法存根 22 Scanner scan=new Scanner(System.in); 23 int a[]={4,0,1,0,2,3,6,0,5}; 24 for(int i=0;i<a.length;i++) 25 { 26 System.out.print(a[i]+","); 27 } 28 System.out.println(); 29 System.out.print("请输入要提前的元素值:"); 30 int x=scan.nextInt(); 31 adjust(a,x); 32 for(int i=0;i<a.length;i++) 33 { 34 System.out.print(a[i]+","); 35 } 36 37 38 } 39 40 }
测试样例输出为:
4,0,1,0,2,3,6,0,5,
请输入要提前的元素值:0
0,0,0,4,1,2,3,6,5,
举一反三:该题目是前移,同样会有后移,读者可以自己尝试编程实现。