Leetcode 704.二分查找

  1. 左闭右闭
    不同的区间就是要对while循环中的判断条件以及right边界做出改变。
    因为是左闭右闭,所以right = nums.size() - 1,即nums[right]可以取到,且循环条件为while(left <= right),因为当right == left时进入循环时有意义的。
  2. 左闭右开
    因为是左闭右开,所以right = nums.size(),即取不到边界值,那么同理当right == left时进入循环时没有意义。

下面给出左闭右开的代码:

     int left = 0;int right = nums.size();while(left < right){int mid = left + (right - left)/2;if(nums[mid] == target) return mid;else if(nums[mid] < target) left = mid + 1;else right = mid;}return -1;

Leetcode 35.搜索插入位置

本题与704唯一不同的地方就是当target在递增数组范围内却找不到时需要插入。
需要注意的点有两个:

  1. 当元素在数组中间位置插入时,这里返回最后一次的mid值即可
  2. 当元素在数组边界位置插入时,尤其是右边界,这种情况需要增加数组的容量才能插入新的元素,所以采用左闭右开的二分法。当循环结束时返回值为原数组长度,相当于新插入的索引。

下面给出代码:

     int left = 0;int right = nums.size();while(left < right){ int mid = left + (right - left)/2;if(nums[mid] == target) return mid;else if(nums[mid] < target) left = mid + 1;else right = mid;}return left + (right - left)/2;

Leetcode 34.在排序数组中查找元素的第一个和最后一个位置

  1. 本题如果采用暴力解法的思路就是,先正序遍历数组找到第一个target出现的位置,再倒序遍历数组找到最后一个target出现的位置。
    下面给出代码:
class Solution {public:vector<int> searchRange(vector<int>& nums, int target) {int left = -1;int right = -1;for(int i = 0; i < nums.size(); i++){if(nums[i] > target) break;if(nums[i] == target){left = i;break;}else continue;}for(int i = nums.size() - 1; i >= 0; i--){if(nums[i] < target) break;if(nums[i] == target){right = i;break;}else continue;}return {left,right};}
};
  1. 但是题目要求时间复杂度为O(log n),所以想到二分法找边界,本题使用左闭右闭的二分法。二分法思路和暴力差不多,但是在算法上做了优化,并且根据卡哥的提示,分开写左右边界的寻找,本题在细节上还是有很多需要注意的地方。
  • 首先就是确定在二分的时候,何时更新左右边界,以右边界为例。
    寻找右边界,需要用左边界不断逼近使循环结束时,left所处位置为target的下一个不等于target的元素。
    所以当target < nums[mid]时是不需要更新右边界的,因为此时不用更新二分中的左边界,同时要找到target元素的边界,在target == nums[mid]时也是要更新的。下面给出代码:
     int left = 0;int right = nums.size() - 1;int rightboarder = -2;while(left <= right){int mid = left + (right - left)/2;if(nums[mid] > target){right = mid - 1;}else{left = mid + 1;rightboarder = left;}}return rightboarder;

左边界同理,使用二分的右边界来不断逼近,使结束循环时nums[right]位于target元素的左边一个位置。最后综合两者来完成主函数。

  • 卡哥在寻找左右边界前先讨论了三种情况,这三种情况下的判断条件也是细节之一。
     int leftboarder = searchleft(nums, target);int rightboarder = searchright(nums, target);//这里是或不是与if(leftboarder == -2 || rightboarder == -2) return {-1,-1};if(rightboarder - leftboarder > 1) return {leftboarder + 1 , rightboarder - 1};return {-1 , -1};

结合寻找左右边界时的思路,就可以写出当target存在于数组时的边界,因为找出的边界是target两侧前一个或后一个元素,所以输出的时候需要对应的+1和-1。另外一个点就是只要左右边界有任意一个不满足条件,那么两者都不满足target在数组中的条件。

Leetcode 27.移除元素

双指针法是本题的精髓。本题相当于是对vector中erase方法的实现,其中慢指针是指向新数组中需要更新的位置,快指针指向新数组的元素。所以当遇到需要删除(覆盖)的元素时,慢指针不动,快指针继续移动;当慢指针当前指向的元素不是需要删除的元素时,慢指针正常移动。
代码如下:

class Solution {public:int removeElement(vector<int>& nums, int val) {int left = 0;for(int right = 0; right < nums.size(); right++){if(nums[right] == val) continue;nums[left] = nums[right];left++;}return left;}
};

额外的知识点

在二分法计算mid时,会有一个操作:mid = left + (right - left)/2,这样是防止mid值的溢出,向群里大佬学习也可以用移位操作来实现。
这里搬运记录一下:

  • 当n为负数时,>> 1/2的结果是一样的
  • 当n为负数且为偶数时,>> 1/2的结果是一样的
  • 当n为负数且为奇数时,>> 1/2的结果是不一样的
    因为奇数除以二会发生截断现象,而此时>> 1/2截断的方向不一样,导致结果不同。
    如:-5 / 2 = -(int)2.5 = -2-5 >> 1 = (1011) >> 1 = (1101) = -3

代码随想录第一天 leetcode 704、35、34、27相关推荐

  1. Leetcode 704.二分查找 27.移除元素 代码随想录day1

    本系列目的在于跟练代码随想录,以及记录自己在数据结构与算法方面的一些学习 704.二分查找 其实之前自己在随便刷题的时候看过这道题目,就是一个纯新手的大状态,第一次听到二分查找这样的东西,然后跟着题解 ...

  2. 代码随想录刷题|LeetCode 332.重新安排行程 51. N皇后 37. 解数独

    目录 332.重新安排行程 思路 重新安排行程 51. N皇后 思路 N皇后 37. 解数独 思路 解数独         这三道题目都是困难题目,都是根据代码随想录的思路总结书写,慢慢理解,慢慢熟练 ...

  3. 代码随想录刷题|LeetCode 1049. 最后一块石头的重量II 494. 目标和 474.一和零

    目录 1049. 最后一块石头的重量 II 思路 最后一块石头的重量|| 494. 目标和 思路 0.求什么 1.确定dp数组的含义 2.递推公式 3.初始化dp数组 4.遍历顺序 目标和 474.一 ...

  4. 代码随想录第一天| 704. 二分查找、27. 移除元素

    数组相关知识 数组下标都是从0开始的. 数组内存空间的地址是连续的 因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址. go声明二维数组时,系统 ...

  5. 【代码随想录】【LeetCode】自学笔记07 - 栈和队列

    总结 基础补牢:[https://blog.csdn.net/tham_/article/details/44733101] 根据[http://c.biancheng.net/view/3354.h ...

  6. 第1天-代码随想录刷题训练| 704二分查找、26移除元素

    文章目录 1. 二分查找704 扩展 2.移除元素 2.1数组理论基础 2.2 暴力解法 2.3双指针解法 2.4 扩展题 1. 二分查找704 原题链接 给定一个 n 个元素有序的(升序)整型数组 ...

  7. 【代码随想录】【LeetCode】学习笔记04-哈希表

    前言 哈希法牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找. 如果遇到需要判断一个元素是否出现过的场景,应该第一时间想到哈希法! 四个常见哈希表类型对 ...

  8. 【代码随想录】二刷-数组

    数组 <代码随想录> 二分查找 704. 二分查找 方法1 注意: 边界控制. 前提是有序数组. 循环控制 解释: 这里使用我最好理解的一种方式. 使用mid控制下标访问,nums[mid ...

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

    今日学习的文章链接如下: 代码随想录 (programmercarl.com) 代码随想录 (programmercarl.com) 704. 二分查找 自己看到题目的第一想法 拿到题目首先想办法,一 ...

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

    代码随想录算法Day1 | 704. 二分查找.27. 移除元素 Last edited time: April 5, 2023 11:27 AM 数据理论基础 数组是存放在连续内存空间上的相同类型数 ...

最新文章

  1. 华为云计算之FusionStorage
  2. 手持GPS坐标系统的转换与应用
  3. abap视图字段限制_MM03物料主数据视图中某些视图或者某些字段的控制方法 | 学步园...
  4. [转载] Java 重写paint绘图
  5. fastdfs-配置存储服务器storage
  6. 网络规划设计师考试总结
  7. Qt学习: QFileDialog和QMessageBox的用法和程序示例
  8. Python+KNN算法判断单词相似度小案例
  9. echarts 设置各省份颜色
  10. 专利服务器拒收 文件解压异常,电子申请常见问题解答20161024.doc-中国专利电子申请网.doc...
  11. C# Abp框架入门系列文章(一)
  12. t分布f分布与样本均值抽样分布_T检验和其他假设检验的P值怎么理解
  13. 社团联合会计算机教程,计算机与信息工程学院学生社团联合会
  14. R | Rstudio安装 |Rstudio空白及显示无法访问此网站
  15. 入侵防御系统 IPS
  16. ui设计一般用什么软件(ui学哪些软件)
  17. 解开关于人工智能的六个迷思
  18. VM安装win7系统一直失败,可能是镜像文件不对
  19. 安装JDK8时错误1335的解决
  20. 报告总结:无线通信中的数学问题

热门文章

  1. 数据库考试内容(MYSQL)
  2. 2018前端走向全栈,Nodejs快速入门视频教程
  3. 多元数量值函数积分学
  4. MacOS下解决宿主机和docker容器之间网络互通
  5. 蓝凌OA前台任意文件读取漏洞利用
  6. STM32——理解时钟系统
  7. Canonical 在 Linux 上提供 Flutter 桌面应用支持
  8. webpack不报错但是图标和字体却无法显示
  9. org.apache.kafka.clients.consumer.OffsetOutOfRangeException: Offsets out of range with no configured
  10. EXCEL学会两个函数你能打败90%的人,countifs和vlookup