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

704.二分查找

题目链接:https://leetcode.cn/problems/binary-search/description/
文档讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715

思路

  • 当区间定义为左闭右开时,right的初始值应该是nums.length,因为区间不包含这个值。left移动时,因为区间包含了left的值,而nums[middle]已经被比较过,所以left移动到middle + 1的位置。right移动时,因为区间没有包含right的位置,所以right应该移动到middle的位置。
  • 当区间定义为左闭右闭时,right的初始值应该是nums.length - 1,因为区间包含这个值,如果是nums.length就没有意义。left移动同上,right移动时,因为区间包含了right的值,而nums[middle]已经被比较过,所以right移动到middle - 1的位置。

代码

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

分析:两种方法均为时间复杂度:O(logn),空间复杂度:O(1)。

总结
之前零零散散刷过一些题,所以对二分法还有点记忆。虽然大概知道开闭的一些需要注意的点,但在实际做的时候还是错了好几次才通过。首先是在循环里没有写middle的赋值,很粗心。然后是忽略了right的初始赋值时开闭区间的问题,导致错误。

27.移除元素

题目链接:https://leetcode.cn/problems/remove-element/
文档讲解:https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP/

思路

  • 暴搜是两层for循环,第一层遍历数组,遇到val相等的,再进入一层for循环把后面所有元素往前移。
  • 快慢指针是快指针fast遍历数组,遇到和val不相等的数就放入慢指针slow,然后慢指针slow++。

代码

class Solution {
    public int removeElement(int[] nums, int val) {
        //暴搜
        int index = 0;
        for(int i = 0; i < nums.length; i++) {
            if(nums[i] != val) {
                nums[index] = nums[i];
                index++;
            }
        } 
        return index;
        
        //双指针
        int fast = 0, slow = 0;
        for( ; fast < nums.length; fast++) {
            if(nums[fast] != val) {
                nums[slow] = nums[fast];
                slow++;
            }
        }
        
        return slow;
    }
}

分析:
暴搜时间复杂度:O(n^2),空间复杂度:O(1)。
快慢指针法时间复杂度:O(n),空间复杂度:O(1)。

总结
移除元素做的还是比较顺的,就是我以为的暴搜其实好像只是另外一种双指针的写法。正常的暴搜应该是两层for循环,第一层遍历数组,遇到val相等的,再进入一层for循环把后面所有元素往前移。

本次目标
一刷代码随想录的时候刷到二叉树就开始懈怠,后面又零零散散做了一些动态规划和贪心算法,但是发现笔试的时候前面刷过的知识点完全运用不起来。希望这次能够坚持两个月,把基础打好,并且掌握二叉树。

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-09 20:38:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-09 20:38:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-09 20:38:03       82 阅读
  4. Python语言-面向对象

    2024-05-09 20:38:03       91 阅读

热门阅读

  1. 数据结构队列学习

    2024-05-09 20:38:03       32 阅读
  2. vue项目开发流程

    2024-05-09 20:38:03       35 阅读
  3. 黑马点评项目笔记

    2024-05-09 20:38:03       29 阅读
  4. LabVIEW实现多张图像拼接

    2024-05-09 20:38:03       26 阅读
  5. c++ 读写锁对比试验

    2024-05-09 20:38:03       35 阅读
  6. Redis-1 缓存穿透、缓存击穿、缓存雪崩

    2024-05-09 20:38:03       25 阅读
  7. 接收文件(文件上传)

    2024-05-09 20:38:03       32 阅读
  8. 内联函数为什么不能声明定义分离?

    2024-05-09 20:38:03       21 阅读