代码随想录算法训练营第一天| 数组理论基础、LeetCode 704二分查找、LeetCode27移除元素

1 数组理论基础

 文章讲解:代码随想录(programmercarl.com)

1.1 数组在内存中的存储方式

        数组是存放在连续内存空间上相同类型数据的集合。

        注:数组的下标都是从0开始的。

2 LeetCode 704 二分查找

题目链接:LeetCode 704 二分查找

文章讲解:代码随想录(programmercarl.com)

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

2.1 思路

        此题的题目中提到了该数组是有序的(升序),且在提示中强调数组中的元素是不重复的,所以此题可以使用二分查找法来进行求解。

        注:二分查找只能实现单值查找,不能实现多值查找,如果数组中元素有重复,那么二分查找法找到的下标可能不唯一。

2.2 二分法注意事项

        二分法容易写乱,主要是没有分清自己定义的区间是左闭右闭[left, right],还是左闭右开[left, right)。这两种区间的定义在做题时都可以使用,但是在一道题目中,只可以选择一种定义方式。

2.2.1 左闭右闭区间写法

        当我们定义target在左闭右闭的区间中,即[left, right],要注意以下两点:

        1.因为left == right是有意义的,在while (条件) 循环的条件中我们使用left <= right,而不是left < right,即while (left <= right)。

        2.当if (nums[middle] > target)判断条件成立时,我们要给right赋值为middle - 1,而不是middle。因为区间是右闭的,在判断条件中,我们已经知道nums[middle] > target,如果right赋值为middle,就会重复做一次判断。

2.2.2 左闭右开区间写法

        当我们定义target在左闭右开的区间中,即[left, right),要注意以下两点:

        1.因为left == right已经没有意义了,在while (条件) 循环的条件中我们不能让left = right,只可以写left < right,即while (left < right)。

        2.当if (nums[middle] > target)判断条件成立时,我们要给right赋值为middle,而不是middle - 1。因为区间是右开的,取不到right的值。所以将right赋值为middle。

2.3 代码

        Java版本的左闭右开区间的写法

        步骤:

                a. 判断目标值是否在数组内

                b. 定义区间(左闭右开)

                c. 进入循环;定义middle;开始判断(3点)

class Solution {
    public int search(int[] nums, int target) {
        if(target < nums[0] || target > nums[nums.length - 1]){
            return -1;
        }
        int left = 0, right = nums.length;// 左闭右开区间
        while (left < right){
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target)
                return mid;
            else if (nums[mid] < target)
                left = mid + 1;
            else if (nums[mid] > target)
                right = mid;
        }
        return -1;
    }
}

        在定义middle时,用到了防溢出的方式:

int mid = left + ((right - left) >> 1); //二进制右移
int mid = left + ((right - left)  / 2);

         二进制右移的运行速度更快。

3 LeetCode 27 移除元素

题目链接:LeetCode 27 移除元素

文章讲解:代码随想录(programmercarl.com)

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

3.1 暴力解法

        两层for循环,一个for循环遍历数组元素,另一个for循环更新数组。

3.2 双指针解法思路

        双指针法(快慢指针法):需要明确快慢指针的作用分别是什么。

        快指针:寻找新数组的元素,新数组就是不含有目标元素的数组。

        慢指针:指向更新,新数组下标的位置。、

3.3 双指针运行过程

        开始时,fast指针和solw指针都指向0位置;

        fast指针先进行判断,判断该位置是否为目标值:

                如果不是目标值就将该值赋值给slow指针,然后后移一位;

                如果是目标值就后移一位,不进行赋值操作。

3.4 双指针解法代码

        Java版本的双指针解法代码

        步骤:

                a. 定义慢指针

                b. 进入循环,并在条件中定义快指针

                c. 进行判断

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 总结

        LeetCode 704 二分查找主要掌握了左闭右闭区间的写法,LeetCode 27 移除元素主要掌握了双指针的解法。

你可能感兴趣的:(代码随想录算法刷题,算法,leetcode,java)