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

LeetCode 704二分查找

题目链接: 二分查找

代码

class Solution {
    public int search(int[] nums, int target) {
        // 剔除超出范围的元素
        while( target < nums[0] || target > nums[nums.length-1]){
            return -1;
        }
        // 定义所用变量
        int left = 0;
        int right = nums.length - 1;
        // 循环
        while (left <= right){
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target){
                return mid;
            }
            else if(nums[mid] < target){
                left = mid + 1;
            }
            else{
                right = mid - 1;
            }
        }
        return -1;
    }
}

个人心得

对于算法逻辑一直都很差。并且在清醒认识到自己的差后,格外不自信,加之太过粗心,每次写代码哪怕最简单的代码,都如同翻山越岭般困难。

希望一刷随想录的过程中,提高自己的细心,耐心和信心,加油!

拿到二分查找,因为遗忘过多,脑袋空空。在看了解析后才想起这个题目的逻辑是多么简单。

  1. 剔除超出范围的元素,可以减少循环次数(这一步骤无脑做题时我可能会忽略的)

  2. 一些很简单的细节比如分号,括号匹配,定义变量等都不能忽视。

  3. 这道题目对自己来说一个稍微困难的点在于 为了提高代码运行效率及考虑到内存问题,将(left + right)/ 2 写成了left + ((right - left) >> 1)。而在编写代码过程中,自己忽略了算术运算符的优先级大于位运算符,一直在报错。

代码不可能说无缘无故和你作对,一定是你有粗心或者忽略的地方,静下心来慢慢检查,或者换一种方式实现,然后去思考原来方法的不对之处。

题目注意点

  1. 针对有序且无重复元素,才可以使用二分查找法

  2. 区间不变量问题:因为涉及到while循环,所以一开始明确是左闭右闭区间,之后就要一直遵循这个区间。

判断while的条件 left <= right是哪种区间时,可以给[left,right] 的left right值设置一个特殊值,例如都为1。如上,可知当区间均闭合时,应该是left <= right;左闭右开时,left < right

PS:左闭右闭体现在left与right的取值上面,left取0,right取nums.length - 1;就是闭区间,right取nums.length就是左闭右开。

27.移除元素

题目链接: 移除元素

暴力求解代码

class Solution {
    public int removeElement(int[] nums, int val) {
        int n = 0;
        for(int i = 0;i < nums.length;i++){
            if(nums[i] == val){
                n++;
                continue;
            }
            nums[i-n] = nums[i];
        }
        return nums.length - n;
    }
}

自己的方法是对暴力求解的优化,减少一层循环:一遍计算有几个val值,一边移动val出现次数的步数。

这次编写代码较为顺利,没有出现细节上的错误。

本题目感受:除了看题目以外,还要注意看题目下面的说明,说明中会较为详细地给出具体说明,并不难。

双指针

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

心得

双指针方法,一个快指针用来遍历,一个慢指针始终用来标识需要覆盖的值,类似于在原数组中建立一个新数组。

在数组中,移除元素,并不能真正地移除,只能覆盖

学习时间

因为刚刚开学,学习任务较轻,加之自己对代码略陌生,花了大量时间在这两节上面,也做了相关拓展题目。到了后面,很浮躁。需要静下心来,和其他学习任务穿插进行,一直看有点烦(捂脸。

你可能感兴趣的:(算法学习,算法,leetcode,数据结构)