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

  •  今日学习的文章链接和视频链接

       代码随想录 (programmercarl.com)

        代码随想录 (programmercarl.com)

  •  自己看到题目的第一想法

        // 第一思路:先是for循环暴力搜索匹配解决

  •  看完代码随想录之后的想法 

        // 开始关注区间了,为什么会有两个区间这个来龙去脉并没有说清楚,可能是我菜。

        //快慢指针所代表的含义更具体,脑海中有指针流动的过程图。

  •  自己实现过程中遇到哪些困难 

        // 困难:区间开闭与循环条件的匹配上。

        //if (nums[fastIndex] != val)判断条件的理解

  •  今日收获,记录一下自己的学习时长

        收获如下,3h

二分查找

// 一个小基础,nums.length和nums.length()的区别,前者length代表数组属性的调用,后者代表String类型length()方法的调用,用于返回该字符串的字符个数。

// 一点想法:

// 第二思路:二分法,区间开闭很关键;"mid值的声明初始化在循环语句中"的这个条件也很关键,用于调整搜索范围,有点递归的意思?

// 某种程度上,right值的定义直接决定了区间"左闭右开-[)"还是"左闭右闭-[]"的形式。这个很关键,这决定了为什么右后面两种区间的甄别。

其中"right = nums.length",表示数组长度,而数组索引从0开始的,则右边界是开区间,与此同时,right值的定义会影响循环判断条件,此时为:"while(left < right)";"right = nums.length - 1"表示最后一个元素索引,属于数组元素,所以是闭区间。此时循环条件为:"while(left <= right)"。

代码进化过程:

// 思路一:暴力循环

// class Solution {

//     public int search(int[] nums, int target) {

//         for (int i = 0; i < nums.length; i++) {

//             if (nums[i] == target) {

//                 return i;

//             }

//         }

//         return -1;

//     }

// }

// 思路二:二分查找,区间[]

// class Solution {

//     public int search(int[] nums, int target) {

//         int right = nums.length - 1;

//         int left = 0;

//         while (left <= right){

//             int mid = (left + right) / 2;

//             if (target == nums[mid]) {

//                 return mid;

//             } else if (target > nums[mid]) {

//                 left = mid + 1;

//             } else if (target < nums[mid]){

//                 right = mid - 1;

//             }

//         }

//         return -1;

//     }

// }

// 思路二调整:二分查找:区间为[)

class Solution {

    public int search(int[] nums, int target) {

        int right = nums.length;

        int left = 0;

        while (left < right){

            int mid = (left + right) / 2;

            if (target == nums[mid]) {

                return mid;

            } else if (target > nums[mid]) {

                left = mid + 1;

            } else if (target < nums[mid]){

                right = mid;

            }

        }

        return -1;

    }

}

双指针

//两层for循环,第一层进行遍历,第二层进行覆盖操作。

// 注意点:需要新定义数组更改后的长度值size,数组的长度是一开始就定义好的,所以在删除数组元素时无法更改数组的长度,只能将其采取一个数值记录

暴力解法:

// class Solution {

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

//                 size--;

//             }

//         }

//         return size;

//     }

// }

// 快慢指针

// 慢指针代表新数组的长度,初始值为0。快指针作为筛选检索器,将不含有val值的数据选出赋给slowIndex新数组。仅仅对数组含有的val值进行了局部覆盖。

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,数据结构)