数组中元素的查找,新增和删除
查找一个元素
新增一个元素
在一个有序的数组里,新增一个元素后,该数组仍有序
有两种方案,直接上代码,大家可以参考注解去理解,在自己敲一遍
方案一:
/**
* @param arr
* @param size 数组已经存储的元素数量
* @param element 待插入的元素元素
* @return
*/
public static int addByElementSequence(int[] arr, int size, int element) {
//size和arr.length都表示元素的数量,都是从1开始编号所以这里包括等号
if (size >= arr.length)
throw new IllegalArgumentException("Add failed. Array is full.");
//初始化插入的位置默认为数组末尾
int index = size;
//找到新元素的插入位置
for (int i = 0; i < size; i++) {
if (element < arr[i]) {
index = i;
break;
}
}
//元素后移,从最后一个元素开始后移
for (int j = size; j > index; j--) {
arr[j] = arr[j - 1]; //index下标开始的元素后移一个位置
}
arr[index] = element;//插入数据
return index;
}
方案二:
/**
* 只使用一次for循环
*
* @param arr
* @param size 数组已经存储的元素数量
* @param element 待插入的元素元素
* @return
*/
public static int addByElementSequence2(int[] arr, int size, int element) {
//size和arr.length都表示元素的数量,都是从1开始编号所以这里包括等号
if (size >= arr.length)
throw new IllegalArgumentException("Add failed. Array is full.");
//初始化插入的位置默认为数组末尾
int index = size;
//元素后移,从最后一个元素开始后移
for (int j = size - 1; j >= 0; j--) {
//后面的元素大于要插入的值前移
if (arr[j] > element) {
//元素向后移动
arr[j + 1] = arr[j];
//记录可插入的位置
index = j;
} else {
//找到符合条件的后退出
break;
}
}
//插入数据
arr[index] = element;
return index;
}
可以看出来,方案二比方案一少了一次for循环,效率更高了一些。
删除一个元素
直接上代码
/**
* 遍历数组,如果发现目标元素,则将其删除,
* 数组的删除就是从目标元素开始,用后续元素依次覆盖前继元素
*
* @param arr 数组
* @param size 数组中的元素个数
* @param key 要删除的目标值
*/
public static 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) {
//这里使用index+1作为起始,是为了避免数组下标越界异常
for (int i = index + 1; i < size; i++)
arr[i - 1] = arr[i];
size--;
}
return size;
}
判断数组是否单调递增、递减
LeetCode 896.判断一个给定的数组是否为单调数组。
分析: 如果对于所有i<= j,A [i]<= A[j],那么数组 A 是单调递增的。如果对于所有i<= j,A [i]>= A[j],那么数组 是单调递减的。所以历数组执行这个判定条件就行了,由于有递增和递减两种情况。代码如下:
/**
* 一次遍历确定
*如果是递增的就一定不能出现递减的相邻元素,
* 如果出现递减的就一定不能出现递增的相邻元素。
* @param nums
* @return
*/
public static boolean isMonotonic(int[] nums) {
boolean inc = true, dec = true;
int n = nums.length;
for (int i = 0; i < n - 1; ++i) {
if (nums[i] > nums[i + 1]) {
inc = false;
}
if (nums[i] < nums[i + 1]) {
dec = false;
}
}
return inc || dec;
}
数组的合并
数组的合并是一些数组相关算法题的基础,比如后面的归并排序等都需要用到
最简单的合并方法有,现将两个数组直接合并到一起,后面在做一个排序即可,代码如下:
/**
* 方法1:先合并再排序实现排序
*
* @param nums1 第一个数组
* @param nums1_len 第一个数组的长度
* @param nums2 第二个数组,将nums2合并到nums1中
* @param nums2_len 第二个数组的长度
*/
public static void merge1(int[] nums1, int nums1_len, int[] nums2, int nums2_len) {
for (int i = 0; i < nums2_len; ++i) {
nums1[nums1_len + i] = nums2[i];
}
Arrays.sort(nums1);
}
另一种方法:
A和B的元素数量是固定的,所以排序后最远位置一定是A和B元素都最大的那个,依次类推,每次都找最大的那个从后向前填就可以了,
代码如下
/**
* 方法2:两个数组从后向前逐步合并
*
* @param nums1
* @param nums1_len
* @param nums2
* @param nums2_len
*/
public static void merge2(int[] nums1, int nums1_len, int[] nums2, int nums2_len) {
int i = nums1_len + nums2_len - 1;
int len1 = nums1_len - 1, len2 = nums2_len - 1;
while (len1 >= 0 && len2 >= 0) {
if (nums1[len1] <= nums2[len2])
nums1[i--] = nums2[len2--];
else if (nums1[len1] > nums2[len2])
nums1[i--] = nums1[len1--];
}
//假如A或者B数组还有剩余
while (len2 != -1) nums1[i--] = nums2[len2--];
while (len1 != -1) nums1[i--] = nums1[len1--];
}