刷题第一天。毫无头绪。加油!
704.二分查找
题目链接:https://leetcode.cn/problems/binary-search/
文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
题目:
给定一个n个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
二分查找:
1.条件:(1)查找的内容逻辑上是有序的;
(2)查找的内容只能有一个。
2.查找区间的范围方式:(1)左闭右闭 [left , right]
(2)左闭右开 [left , right)
3.数组长度是奇数或者偶数,都不影响算法如何排除的问题。
4.真正影响的是 中间的那个数字是否应该加入下一次的查找中,即边界问题。
相关知识学习参考以下链接:【二分查找】详细图解_二分查找法流程图-CSDN博客
https://blog.csdn.net/qq_45978890/article/details/116094046
二分法思想:
整个数组是有序的,数组默认为递增,并且查找的数字是唯一的。
1.首先找到数组中心点mid的值,与目标值val比较大小;
2.(1)如果中心值mid等于目标值val,输出中心值mid;
(2)中心值mid小于目标值val,那么val位于数组的右半部分,则中间值mid左边的所有数字都小于目标值,全部排除;
(3) 中心值mid大于目标值val,那么val位于数组的左半部分,则中间值mid右边的所有数字都大于目标值,全部排除;
解答:
分为两种,左闭右闭 和 左闭右开。
代码的重点是关注 区间的边界问题。
1.左闭右闭 [ left , right ]
left = 0 ; right = size - 1;
这种情况下,区间就是 左闭右闭,那么此时的循环条件就是 while (left <= right)。
因为左闭右闭区间,在选取区间不断变小的情况下,最终选择的点是 左右边界重合的时候所取到的,所以循环 left <= right。
2.左闭右开 [ left , right )
left = 0; right = size;
这种情况下,区间就是 左闭右开,那么此时的循环条件就是 while (left < right)。
因为左闭右开区间,在选取区间不断变小的情况下,如果循环是 left <= right ,那么会导致左右边界取到同一点,但是左边界可以取到,而右边界却无法取到,属于无效空间,这样会陷入死循环。所以,循环为 left < right。
C++:
· 时间复杂度:O(log n)
· 空间复杂度:O(1)
· 时间复杂度:O(log n)
· 空间复杂度:O(1)
C :
其中,mid=left+(right-left)/2,等同于mid=(left+right)/2,但是left+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
视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP
题目:
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
注:是原地移除,是在该数组上进行移除,并不能创建出新的数组。
移除元素:
1.数组元素在内存地址上是连续的,且不存在物理意义上的删除,只有覆盖。
2.移除元素,即覆盖元素。有两种方法:
(1)暴力实现,用双层for循环;
(2)双指针,快慢指针,一层for循环。
思想:
1.暴力实现。
第一层for循环,遍历整个数组,寻找到目标值val之后,利用第二层for循环,将后面不等于目标值val的元素依次向前移动,覆盖掉目标值val。
一个for循环遍历数组元素 ,第二个for循环更新数组。
时间复杂度:O(N^2) 空间复杂度:O(1)
2.双指针(快慢指针)
· 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
· 慢指针:指向更新 新数组下标的位置
使用快慢指针对数组进行遍历,如果 fast
指针遇到值为 val
的元素,直接跳过,等待 slow
指针将其覆盖,从而达到删除元素的效果;如果 fast
指针遇到值不等于 val
的元素,将其值赋值给 slow
指针,然后让 slow
指针前进一步。
时间复杂度:O(N) 空间复杂度:O(1)
解答:
1.暴力解法
2.双指针
双指针分为:左右指针和快慢指针,本方法使用的是快慢指针。