代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素

题目:

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

35. 搜索插入位置 - 力扣(LeetCode)

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

需要知识:

        数组:对于java的数组来说,内存管理是交给虚拟机管理的,地址是虚拟地址

        数组初始化:int[] nums = {0,....,0};、int[] nums = new int[size];

        数组方法:nums.length

        二分法:对于已经排序好的数组有效

参考资料:代码随想录 (programmercarl.com)

1.二分查找一个数:

代码:

要点:要有边界值的概念,如果left=0,right=长度,这说明包括两个指针在内的值都有可能是target

所以whlie的条件是left<=right

class Solution {
    public int search(int[] nums, int target) {
        //左边从数组下标0开始
        int begin = 0;
        //右边从数组中最后一位数开始
        int end = nums.length - 1;
        //获取数组中间下标,因为mid的更新依赖于begin和end
        int mid = (begin + end) / 2;
        //进入循环,因为在边界上也可能存在target(由begin和end从哪里开始决定)
        while (begin <= end){
            //进入左边
            if(target < nums[mid]){
                end = mid - 1;
                mid = (begin + end) / 2; 
            //进入右边
            } else if(target > nums[mid]){
                begin = mid + 1;
                mid = (begin + end) / 2;
            //找到了
            } else{
                return mid;
            }
        } 
        return -1;
    }
}

2.二分查找到合适的位置(从左到右)

要点:一:对于target在数组中的情况,mid最后总会在left位置上(三种情况:mid 直接等于target不说、target在left边界上,数组长度为奇数则mid和left和right在同一位置上,数组长度为偶数则mid和left在同一位置上,right在left+1);二:对于没有target在数组中的情况(总之就是left和right会把target本应该在的位置夹住):1.left会先和right地址相差一位,2.接着mid会和他们地址相等,3.接着right会往左一个而跳出循环,所以最后mid和left的位置相同,在大于target的最小一个数的地址,

(原因:1.是向下取整,所以就算target在right边界上,right也会不断的等left抵达它的位置)

class Solution {
    public int searchInsert(int[] nums, int target) {
            int begin = 0;
            int end = nums.length - 1;
            //为了不再一次调用nums.length函数,就这样写了
            int result = end + 1;
            while(begin <= end){
                int mid = (begin + end) / 2;
                if(target <= nums[mid]){
                    result = mid;
                    end = mid - 1;
                }else {
                    begin = mid + 1;
                } 
            }
            return result;
            //return end + 1;return begin;一样的效果    
    }
}

3.双指针

要点:要想象有一只章鱼,他的头是慢指针,触手是快指针

class Solution {
    public int removeElement(int[] nums, int val) {
        // 快慢指针
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
            if (nums[fastIndex] != val) {
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;
    }
}

4.总结:思想都理解,但实际上手还是生疏,为了不知其然不知其所以然,花费了一番力气

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值