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

查找一个元素

新增一个元素

在一个有序的数组里,新增一个元素后,该数组仍有序
有两种方案,直接上代码,大家可以参考注解去理解,在自己敲一遍
方案一:

 /**
     * @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--];
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值