数组的增删改查可能你乍一听就会觉得:呵!这还不简单?等到你自己写写看的时候你会发现你写出来不是跑不起来,就是下标对不上就是内存溢出。千万不要小看数组!!算法中最多的题型就是数组题,请大家务必熟练掌握数组的增删改查!!
查找数组元素
为什么数组的题目特别多呢,因为很多题目本质就是查找问题,而数组是查找的最佳载体。很多复杂的算法都是为了提高查找效率的,例如二分查找、二叉树、红黑树、B+树、Hash和堆等等。另一方面很多算法问题本质上都是查找问题,例如滑动窗口问题、回溯问题、动态规划问题等等都是在寻找那个目标结果。
下面是简单实现:
public static int findByElement(int[]arr,int size,int key){
for (int i =0;i<size;i++){
if (arr[i]==key){
return i;
}
}
return -1;
}
来看一道相关的算法题:
这就是查找的变式,查找一个有序数组,在查找过程中找到插入位置时停下。实现起来并不难:
public int searchInsert(int[] nums, int target) {
int index=nums.length;
for(int i=0;i<nums.length;i++){
if(nums[i]>=target){
index=i;
break;
}
}
return index;
}
有一点需要强调,分析一下为什么要将index=nums.length?
增加数组元素
增加元素是数组中最基本的操作了,别以为他简单,其实有很多值得注意的地方。
将给定的元素插入到有序数组的对应位置中,我们可以先找位置,再将其后元素整体右移,最后插入到空位置上。这里需要注意,算法必须能保证在数组的首部、尾部和中间位置插入都可以成功。该问题貌似一个for循环就搞定了,但是如果面试直接让你写并能正确运行,我相信很多人还是会折腾很久,甚至直接会挂。因为自己写的时候会发现游标写size还是size-1,判断时要不要加等于等等,这里推荐一种实现方式。
public static int addByElementSequence(int[]arr,int size,int element){
//问题1:是否应该是size>arr.length
if (size >=arr.length){
retrun -1;
}
//问题2:想想这里是否是index=0或者size-1?
int index = size;
//找到新元素的插入位置,问题3:这里是否应该是size-1?
for (int i=0;i<size;i++){
if (element < arr[i]){
index = i;
break;
}
}
//元素后移,问题4:想想这里为什么不是size-1
for (int j=size;j>index;j--){
arr[j]=arr[j-1];//index下标开始的元素后移一个位置
}
arr[inde]=element;//插入数据
return index;
}
可见在增加数组中我们不仅要考虑到如何将整体元素往后移动,还要考虑到特殊情况在数组头和尾增加的情况,插入时数组是否溢出等情况。看看代码中的几个问题你能不能弄清楚。
问题1:size表示的是元素的个数,length是数组的长度即容纳量,此时只要size等于length就不能再添加啦。再添加就会溢出。
问题2:这里将index=size是考虑到在数组最后插入元素的情况,此时数组的长度为size,最后一个的下标为size-1,则要插入位置的下标为size。
问题3:这i<size是为了遍历整个数组嘛,从下标为0到下标为size-1。
问题4:此时是为了将所有的元素向后移动(从后向前),size表示的是移动后的下标。
除了上面的方式,还可以一开始就从后向前一边移动一边对比查找,找到位置直接插入。
public static int addByElementSequence(int[]arr,int size,int element){
if (size >=arr.length){
retrun -1;
}
int index = size;
//找到新元素的插入位置,问题3:这里是否应该是size-1?
for (int i= size;i>0;i--){
if (element < arr[i-1]){
arr[i]=arr[i-1];
}else{
index = i;
break;
}
}
arr[inde]=element;//插入数据
return index;
}
删除数组元素
删除元素要注意一点,一定要先确保删除的元素是否存在,所以删除时就不能用变移动边对比的方法了。其他跟增加元素的方法没有区别。
public int removeByElement(int[]arr,int size,int key){
int index =-1;
//找到要删除的元素的位置
for (int i=0;i<size;i++){
if (arr[i]==key){
index = i;
break;
}
}
//将元素向前移动
if (index !=-1){
for (int i = index+1;i<size;i++)
arr[i-1]=arr[i];
size--;
}
return size;