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

目录

LeetCode 704.二分查找

LeetCode 27.移除元素


 LeetCode 704.二分查找

 文档讲解:代码随想录

视频讲解:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili

力扣题目:力扣

代码随想录算法训练营第一天|LeetCode 704、二分查找 LeetCode 27、移除元素_第1张图片

题目获取的信息:

第一:有序且为升序,元素不重复的数组

第二:在数组中找到对应target的值

第三:有则返回对应target的下标,无则返回-1

思路:

1.使用二分查找的前提有两个:1是有序的数组,2是数组元素不重复,题目都符合要求。

2.在二分查找过程中,不断进行折半处理。而在折半处理的过程中,数组的范围是在不断缩减的,所以会联想到要用循环体。在这个过程中,影响着3个变量,这3个变量来控制数组范围,也即是left(左边界),right(右边界),middle(中间下标)。

3.定义left = 0;right = nums.length - 1; middle = (left + right) / 2;

3.那么循环体的条件该如何定义呢?如果是左闭右开区间,假设一开始的nums[middle]>target,因为nums为升序数组,所以可以得知target是在[left, middle]这个区间的。相应的我们要对判断条件中的right值来进行修改,right = middle。为什么不是right = middle - 1呢?因为我们是左闭右开区间,在循环判断条件中,并没有帮我们判断右区间,所以我们要在循环体内的判断进行相应的修改;同理,要是左闭右闭区间,假设一开始的nums[target]>target,因为nums为升序数组,所以可以得知target是在[left, middle)这个区间的。因为循环判断条件中以及帮我们判断了右区间,所以在循环体内的判断条件可以中,right = middle - 1;

所以综上所述:

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

        return -1;
    }
}


LeetCode 27.移除元素

文档讲解:代码随想录

视频讲解:数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili

题目:力扣

代码随想录算法训练营第一天|LeetCode 704、二分查找 LeetCode 27、移除元素_第2张图片

看到题目要原地修改的时候,会想到双指针的解法。但实际操作下来,会发现还是会用回原来的暴力解法,而没有想到用快慢指针的操作。

暴力解法思路:定义两个循环体,第一个循环体遍历整个数组,第二个循环体则用来更新数组。

class Solution{
    
    public int removeElement(int[] nums, int val){
        
        int length = nums.length;

        for(int oneIndex = 0; oneIndex < nums.length; oneIndex++){
            
            if(nums[oneIndex] == val){    

                for(int twoIndex = oneIndex + 1; twoIndex < nums.length; twoIndex++){
                    
                    nums[twoIndex - 1] = nums[twoIndex];
                    
                }

                oneIndex--;
                length--;
            }
        }

        return length;
    }
}

快慢指针的思路:首先在for循环中定义一个快指针fastIndex,fastIndex就是用来遍历整个数组。其次,思考慢指针在快指针遍历的数组的过程中,如何慢下来,也就是思考判断条件。

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;
    }
}

你可能感兴趣的:(算法,leetcode,职场和发展)