算法训练营day01|数组理论基础|704.二分查找,27.移除元素

1.知识点

1.1数组基础理论

数组中的地址是连续的

对于二维数组:

c++语言中,二维数组也是连续的

java语言中,二维数组不是连续的

1.2二分查找

对于有序数组相关的问题,可以考虑二分法

1.3双指针

双指针(快慢指针,双向指针)在考察数组,链表,字符串等操作的题目中较常用

2.刷题

704.二分查找

LeetCode链接:704. 二分查找 - 力扣(LeetCode)

题目描述

方法1:二分查找

package daimasuixiangshuati.day01_shuzu;

/**
 * @Author LeiGe
 * @Date 2023/9/20
 * @Description todo
 */
public class ErFenChaZhao704_1 {
    /**
     * 二分查找
     *
     * @param nums
     * @param target
     * @return
     */
    public static int search(int[] nums, int target) {
        //区间左侧
        int left = 0;
        //区间右侧
        int right = nums.length - 1;

        // 采用[左闭右闭的区间策略]
        while (left <= right) {
            // 求出区间中点位置
            int mid = left + ((right - left) >> 1);

            // nums[mid] > target: 说明target在mid左侧,那么更新区间右边界
            if (nums[mid] > target) {
                right = mid - 1;
            }
            // nums[mid] < target: 说明target在右侧,那么更新区间右边界
            else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                return mid;
            }
        }
        return -1;
    }
}

时间复杂度:O(logN)

空间复杂度:O(1)

注意点:在计算区间中点位置的时候用int mid = left + ((right - left) >> 1)代替int mid = (left + right) / 2;

这样的好处是:1.可以避免相加溢出 2.采用位运算加速

27.移除元素

LeetCode链接:27. 移除元素 - 力扣(LeetCode)

题目描述

方法1:暴力

package daimasuixiangshuati.day01_shuzu;

/**
 * @Author LeiGe
 * @Date 2023/9/20
 * @Description todo
 */
public class YiChuYuanSu27_1 {

    /**
     * 方法1:暴力-每次删除一个元素后,数组中此位置后的所有数都往前移动
     *
     * @param nums
     * @param val
     * @return
     */
    public int removeElement(int[] nums, int val) {
        int size = nums.length;
        for (int i = 0; i < size; i++) {
            // 发现是要删除的元素,数组中所有元素向前移动一位
            if (nums[i] == val) {
                for (int j = i + 1; j < size; j++) {
                    nums[j - 1] = nums[j];
                }
                // 下标i处的值被删除了,所以i要往前移动一位
                i--;
                size--;
            }
        }

        return size;
    }
}

时间复杂度:O(N^2)

空间复杂度:O(1)

方法2:快慢指针-不改变原数组中元素相对位置

package daimasuixiangshuati.day01_shuzu;

/**
 * @Author LeiGe
 * @Date 2023/9/20
 * @Description todo
 */
public class YiChuYuanSu27_2 {

    /**
     * 方法2:快慢指针
     * 如果快指针的值不等于val,那么就将快指针处的值移动到慢指针处
     * 最后慢指针所处的位置就是删除元素后数组的长度
     * @param nums
     * @param val
     * @return
     */
    public static int removeElement(int[] nums, int val) {
        int size = nums.length;
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < size; fastIndex++) {
            if (nums[fastIndex] != val) {
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }

        return slowIndex;
    }
}

时间复杂度:O(N)

空间复杂度:O(1)

方法3:相向双指针-改变了原数组中元素相对位置

package daimasuixiangshuati.day01_shuzu;

/**
 * @Author LeiGe
 * @Date 2023/9/20
 * @Description todo
 */
public class YiChuYuanSu27_3 {

    /**
     * 方法3:相向双指针法
     * 0.左指针在最左边,右指针在最右边
     * 1.从左边找到等于val的位置
     * 2.从右边找到不等于val的位置
     * 3.将右边不等于val位置的数覆盖到左边等于val位置
     * 4.循环结束后,left指针所处的位置就是新数组的长度
     *
     * @param nums
     * @param val
     * @return
     */
    public static int removeElement(int[] nums, int val) {
        int left = 0;
        int right = nums.length - 1;

        while (left <= right) {
            //找左边等于val的元素
            while (left <= right && nums[left] != val) {
                left++;
            }

            //找右边不等于val的元素
            while (left <= right && nums[right] == val) {
                right--;
            }

            // 将右边不等于val的元素覆盖到左边等于val的元素
            if (left < right) {
                nums[left] = nums[right];
                left++;
                right--;
            }
        }

        return left;
    }
}

时间复杂度:O(N)

空间复杂度:O(1)

3.小结

1.对于有序的数组,可以考虑二分

2.双指针常用的类型有快慢指针,相向双指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值