代码随想录Day1 | 704. 二分查找,27. 移除元素

Day1

前言

今天是算法小白的第一天,坚持就是胜利

文章:代码随想录

视频:算法公开课-跟着Carl学算法

LeetCode 704 二分查找

自己思路

没有算法基础,没有意识到二分法,直接就是无脑for循环解决,做出来还沾沾自喜

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

看完讲解

明白了二分法循环不变量,感觉归根结底是数学问题,至于左闭右闭还是左闭右开,middle+1还是middle-1还是middle的问题,也需要结合数学的边界问题来看,考虑边界值是否被比较过来判断,但是记得从始至终保持同一个区间原则即可(我更适应左闭右闭的思路)

区间的定义就是不变量,那么在循环中坚持根据查找区间的定义来做边界处理,就是循环不变量规则。

写二分法代码的时候,遇到两个问题:

第一个是left,right,middle应该对应数组下标,而不是数组的值,因为这样求出的middle不一定是数组的元素

第二个是每次循环都需要更新middle的值,所以middle赋值需要放在循环内的开始位置

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 (target < nums[middle]) {
                right = middle - 1;
            }else if (target > nums[middle]) {
                left = middle + 1;
            }else if (target == nums[middle]){
                return middle;
            }
        }
        return -1;
    }
}

LeetCode 27 移除元素 

自己思路

首先读题发现我对一些专业术语的理解不够,算法基础比较差。写的过程就感觉自己的思路很混乱很麻烦,只知道是遍历匹配然后数组前移,但是后面空出的位置如何处理很模糊,还有移动后数组的下标i是不是也要前移,只能不停地改不停地测试,第一次使用力扣,有一些报错都还看不懂,最后挣扎半小时测试用例通过了,但提交执行出错,放弃,看讲解吧

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

看完讲解

首先是暴力两层循环法,我的问题在于for循环的范围,随着数组元素的减少,那么两层循环范围也应当一起减少。同时,数组后面空出的位置可以直接不处理,不需要像我前面那样置0,毕竟万一val就是0,再加上我的范围还没有随之缩小,就会出大问题

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];
                }
                size--;
                i--;
            }
        }
        return size;
    }
}

更推荐也是最重要的解法,双指针思路,用两个指针来在数组中移动,fast可以理解为遍历原数组寻找可以留下的数,low表示留下的数依次排列的序号。由于每当有一个可以留下的数,low就会+1右移,所以最终新数组的长度就是low(严格讲叫slow,我这里都打错了就这样吧)

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

总结

用时:接近4h,第一天很不熟练,也算是对博客格式进行了学习

第一次使用力扣来写代码,缺少了IDEA的提示和一些快捷键,还不习惯,但这也是打磨自己代码规范的一种方式,这种场景应该更接近于之后面试的感觉吧

算法基础确实比较缺乏,下次如果用自己的方法太久没做出来可以放弃,直接去学习算法的思维更重要。晚上补一补时空复杂度以及黑马Java上的常见算法

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值