第一天打卡:移除元素需要重做

编程题解析:二分查找及其变体
文章介绍了使用递归和迭代两种方式实现二分查找算法,并提供了去除数组中特定元素的两种解决方案。此外,还讲解了搜索插入位置问题,利用二分查找特性优化处理。

Day 1

  1. Binary Search

Code:
(Using recursion)

class Solution {
    private int helper(int[] nums, int target, int start, int end){
        if(start > end){
            return -1;
        }
        int mid = (start + end) >> 1;
        if(target == nums[mid]){
            return mid;
        }else if(target > nums[mid]){
            return helper(nums, target, mid+1, end);
        }else{
            return helper(nums, target, start, mid-1);
        }

    }
    public int search(int[] nums, int target) {
        return helper(nums, target, 0, nums.length-1);
    }
}

(Using iteration)

  class Solution {
    public int search(int[] nums, int target) {
        int start = 0, end = nums.length-1;
        while(start <= end){                              // line 1
            int mid = (start + end) >> 1;
            if(nums[mid] == target) return mid;
            if(target < nums[mid]){
                end = mid-1;                              // line 2
            }else{
                start = mid+1;
            }
        }   
        return -1;
    }
}

There’s a variation towards this classic code. Line 1 can be while(start < end), then line 2 becomes end = mid.

  1. 需要练习:Remove Element
    I peeked at the solution…but first solution is

     class Solution {
        public int removeElement(int[] nums, int val) {
            int slow = 0;
            for(int fast = 0; fast < nums.length; ++fast){
                if(nums[fast] != val){
                    nums[slow] = nums[fast];
                    ++slow;
                }
            }
    
            return slow;
        }
    }
    

不要考虑等于的时候怎么停住慢指针;考虑不等于的时候更新慢指针,这样等于的时候慢指针就不动了!

Second solution finds it on both sides

 class Solution {
    public int removeElement(int[] nums, int val) {
        int left = 0, right = nums.length-1;
        while(left <= right){
            while(left <= right && nums[left] != val){
                ++left;
            }
            while(left <= right && nums[right] == val){
                --right;
            }
            if(left < right){
                nums[left++] = nums[right--];
            }
        }

        return left;
    }
}

两头寻找元素,遇到符合条件的就换。left <= right 避免越界,=是为了判断最后一个。

  1. Search Insert Position

     class Solution {
        public int searchInsert(int[] nums, int target) {
            int start = 0, end = nums.length-1;
            while(start <= end){
    
                if(start == end){
                    if(target <= nums[start]) return start; // 因为binary search的特点
    
                    return start+1;
                }
                int mid = (start+end) >> 1;
         
                if(nums[mid] == target){
                    return mid;
                }else if(nums[mid] > target){
                    end = mid-1;
                }else{
                    start = mid+1;  //这里,start会自动向上合并
                }
            }
            
            return start;
        }
    }
    

Binary search 最后都会变成start = index, end = index+1 这种相邻的情况,这时候,mid总会是start(较小数)。之后,如果一个元素在start和end之间,start会归并到end,所以<和=的情况都是return start; 如果target比这个都大,则return start + 1;

class Solution {
    public int searchInsert(int[] nums, int target) {
        // 要找一个大于等于target的数组下标!
        int start = 0, end = nums.length-1, ans = nums.length;
        while(start <= end){
            int mid = (start+end) >> 1;
     
            if(nums[mid] == target){
                return mid;
            }else if(nums[mid] > target){
                ans = mid;
                end = mid-1;
            }else{
                start = mid+1;
            }
        }
        
        return ans;
    }
}

答案的solution言简意赅,见comment!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值