算法Day1|704. 二分查找、27. 移除元素

刷题第一天。毫无头绪。加油!


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博客icon-default.png?t=N7T8https://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.双指针

 

双指针分为:左右指针和快慢指针,本方法使用的是快慢指针。

  • 48
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值