算法通关村 —— 不简单的数组增删改查

目录

算法通关村 —— 不简单的数组增删改查

1 数组创建和初始化

2 数组元素查找

3 数组增加元素

3 删除数组元素


算法通关村 —— 不简单的数组增删改查

在面试中,数组大部分情况下都是int类型的,接下来我们就用int类型来实现数组增删改查的基本功能,接下来就让我们自己动手来实现吧。

1 数组创建和初始化

// 创建和初始化数组
// 第一种:直接创建数组然后通过循环赋值
int[] arr = new int[10];
for (int i = 0; i < 5; i++) {
    arr[i] = i+1;
}
// 第二种
int[] arr2 = new int[]{0,1,2,3,4,5};
// 简化
int[] arr3 ={0,1,2,3,4,5};

第一种方法是先创建一个指定长度的数组,然后再通过循环对其赋值。但是这种方式在面试题中一般不行,因为很多题目会给定若干测试数组让你预测通过,例如像[1, 4, 6, 8, 9, 10]这样的数组就不好初始化了。所以采用第二种方法更好,很简单且实用。但注意在创建数组时大小就是元素的数量,是无法再插入元素的,如果需要增加新元素就不能这么用了。

2 数组元素查找

数组很多题目本质就是查找问题,而数组是查找到最佳载体,所以数组的题目特别多。很多复杂的算法都是为了提高查找效率,例如二分查找、二叉树、红黑树、B+树、Hash和堆等等。另一方面很多算法问题本质上都是查找问题,例如滑动窗口问题、回溯问题、动态规划问题都是在寻找目标结果。

查找元素有很多方式,下面是根据值是否相等来进行线性查找,基本实现代码如下:

/**
 * 按值查找
 * @param arr 查找数组
 * @param size 数组元素数量
 * @param key 查找元素值
 * @return 相同元素索引
 */
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;
}

下面再实现根据索引来查找相应元素的值,代码如下:

/**
 * 按索引查找
 * @param arr 查找数组
 * @param size 数组元素数量
 * @param index 查找元素索引
 * @return 相同元素值
 */
public static int findByIndex(int[] arr, int size, int index){
    if (index > size - 1){
        return -1;
    }
    for (int i = 0; i <= size; i++){
        if (i == index){
            return arr[i];
        }
    }
    return -1;
}

若数组是递增的,查找时如果相等或当前位置元素比目标值更大就停下了,下面是实现代码:

public static int findByElementInc(int[] arr, int size, int key){
    for (int i = 0; i <= size; i++){
        if (arr[i] == key){
            return i;
        } else if (arr[i] > key){
            return -1;
        }
    }
    return -1;
}

3 数组增加元素

增加和删除元素是数组最基本的操作,将给定的元素插入到有序数组的对应位置中,我们可以先找位置,再将其后的元素整体右移,最后插入到空位置上。这里要注意,算法必须能保证在数组的首部、尾部和中间位置插入都可以成功。下面是基本实现代码:

/**
 * 增加元素
 * @param arr 数组
 * @param size 数组元素数量
 * @param element 增加元素值
 * @return 增加元素的索引
 */
public static int addByElementSequence(int[] arr, int size, int element){
    // 若数组元素数量已达到数组最大大小,则报错
    if (size >= arr.length)
        return -1;
    // 若比数组元素都大,则直接插在索引为size,即最后的位置
    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];
    }
    // 插入元素
    arr[index] = element;
    return index;
}

除了上面的方式,还可以一开始就从后向一边移动一边查找,找到位置直接插入。这样效率更高,因为只遍历了一次,实现代码如下:

/**
 * 增加元素 - 从后往前找
 * @param arr 数组
 * @param size 数组元素数量
 * @param element 增加元素值
 * @return 增加元素的索引
 */
public static int addByElementSequence2(int[] arr, int size, int element){
    // 若数组元素数量已达到数组最大大小,则报错
    if (size >= arr.length)
        return -1;
    // 若比数组元素都大,则直接插在索引为size,即最后的位置
    int index = 0;
    for (int i = size - 1; i >= 0; i--){
        // 找到位置。存下索引
        if (element < arr[i]){
            arr[i+1] = arr[i];
        }else if (element >= arr[i]){
            arr[i+1] = element;
            index = i + 1;
            return index;
        }
    }
    // 若目标值比所有元素都小,则添加到第一个位置
    arr[0] = element;
    return index;
}

3 删除数组元素

对于删除,就不能一边从后向前移动一边查找了,因为我们不确定删除的元素是否存在。

所以要分为两个步骤,先从最左侧开始查是否存在元素,如果元素存在,则从该位置开始执行删除操作。实现代码如下:

/**
 * 按值删除
 * @param arr 删除的数组
 * @param size 数组大小
 * @param key 删除元素值
 * @return 数组大小
 */
public static int deleteByElement(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 j = index + 1; j < size; j++ ){
            arr[j-1] = arr[j];
            // 数组大小减一
        }
        size--;
    }
    return size;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值