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

news2024/10/6 12:19:47

文章目录

    • Leecode 704.二分查找
    • 题目连接:[Leecode 704.二分查找](https://leetcode.cn/problems/remove-element/)
    • 遇到的问题
    • 题目
    • 二分法的第一种写法 (左闭右闭)
      • 第二种解法(左闭右开 代码呈现)
    • Leecode 27.移除元素
    • 题目链接:[Leecode 移除元素](https://leetcode.cn/problems/remove-element/)
    • 遇到的问题
    • 代码实现
      • 暴力解法
      • 快慢指针
    • 总结
    • 今日收获

Leecode 704.二分查找

题目连接:Leecode 704.二分查找

遇到的问题

对右位运算符那块不太理解后来 方大佬給整明白了。

题目

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

在这里插入图片描述

示例1

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例2

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

思路
这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。

在决定使用二分查找法之前,确定数组是否有序,如果没有 要进行排序操作

二分查找涉及的很多的边界条件,逻辑比较简单,但就是写不好。例如到底是 while(left < right) 还是 while(left <= right),到底是right = middle呢,还是要right = middle - 1呢?

边界条件是一大难点,即确定是左闭右闭还是左闭右开
如果是右闭的情况 即下标等于right 那么在移动下标时就要注意 要减去重合得地方 所以
下一个right = middle -1

大家写二分法经常写乱,主要是因为对区间的定义没有想清楚,区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。

写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。

下面我用这两种区间的定义分别讲解两种不同的二分写法。

接下来就来演示代码

二分法的第一种写法 (左闭右闭)

第一种写法,我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要非常重要)。
区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点:

  • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1

例如在数组:1,2,3,4,7,9,10中查找元素2,如图所示:
在这里插入图片描述

下面提供我的AC代码

> public class BinarySearch {
    //先做左闭右闭的情况
    public int search(int nums[],int target) {
        //避免当target 小于nums[0] ,nums[nums.lenth-1] 时多循环运算
        if (target < nums[0] || target > nums[nums.length-1])
        // 这里呢 进行一个排除 如果说目标的值小于最小 大于最大,那就直接退出
        //运算了
        {
            return -1;
        }
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int middle = left + ((right - left) / 2); //这里防止溢出
            // 右位运算符的而写法是
          //int  middle =left+ ((right-left)>>1);  //下面详细解释一下为什么这么左
            if (nums[middle] > target) {
                right = middle - 1;    //这部分的理解 可以通过画图来深刻了解一下
            } else if (nums[middle] < target) {
                left = middle + 1;
            } else {
                return middle;
            }
        }
        return -1;
    }

通过我画的这个图就可以试着理解一下 right 和left下标的运动原理了
在这里插入图片描述

右位运算符这里引用一下 大佬的原文

int  middle =left+ ((right-left)>>1); 

这个写法等同于(left + right ) / 2,
如果right - left的结果是一个奇数,就会算出一个浮点数出来,比如5 / 2的结果是2.5,数组里没有2.5 这个下标的元素,这就看你用的语言默认取整是怎么做的,所以就会出现问题。用右移运算符是直接做位运算,遇到奇数也能解决。

第二种解法(左闭右开 代码呈现)

 // 左闭右开
    public int search2(int nums[],int target  )
    {
        int left=0;
        int right=nums.length;
        while(left<right) {
            int middle = left + ((right - left)>>1);  // 在左闭右开的情况下这个middle 的取值
            //什么是右运算符
            if(nums[middle]> target)
            {
                right=middle;
            }
            else if(nums[middle]<target)
            {
                left=middle+1;  // 这里需要注意 因为左闭所以要注意左边下标在变化的时候要+1;
            }
            else
            {
                return middle;
            }

        }
        return -1;   //退出
    }

}

Leecode 27.移除元素

题目链接:Leecode 移除元素

遇到的问题

暴力解法很自在,一看就懂 两个循环 第一次在数组遍历
第二次 如果if相同就在将数组进行进位变化
快慢指针解法
之前一听指针脑袋都大 ,今天弄完感觉还行

代码实现

暴力解法

 public int remove(int nums[],int var)
    {
        int size =nums.length; //遍历需要的范围,也就是数组的长度
        //第一波循环遍历数组寻找 等于 var
        for(int i=0;i<size;i++)
        {
            if(nums[i]==var)  //第二次循环就是将数组迁移
            {
                for(int j=i+1; j<size;j++)
                {
                    nums[j - 1] = nums[j];
                }
                i--;
                size--;
            }
        }
        return size;
    }

快慢指针

   //快慢指针的remove
    public int remove2(int nums[],int var)
    {
        int size =nums.length;
        int slowIndex=0 ;//定义慢指针;只需要一层for循环
        for (int fastIndex=0;fastIndex<size;fastIndex++)  //fastIndex是数组中不等于var的下标
        {
            if (nums[fastIndex]!=var)   //slowIndex是新数组的下标
            {
                nums[slowIndex++] = nums[fastIndex];  //则把不等于要删除的值都放到新数组里,最后返回一个
            }
        }
        return slowIndex;  //新数组中的大小;
    }

}

总结

1.暴力解法

在找到要移除的val后,数组整体左移进行删除,此时在进入下一次循环时需要考虑到指针i的位置发生了变化,数组的长度也发生了变化,因此需要更新二者后再进入循环。

2.双指针法

定义快慢指针,快指针遍历数组,寻找val之外的元素,组成不含val元素的新数组;
慢指针指向新数组的元素,一次循环后需要右移一位以便接收下次循环快指针找到的元素,当快指针遍历完nums,快指针的下标实际上就是新数组的长度。

在原数组的废墟上建立新的堡垒

今日收获

1 第一次AC 然后满兴奋的,
2 一有问题大家解决的好快,自己感觉写的博文还有些乱
3 向方大佬致敬 我也打算弄一下模板了 不然要好久

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/124205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis【创建与使用】

MyBatis【创建与使用】&#x1f34e;一. MyBatis&#x1f352;1.1. MyBatis 是什么&#xff1f;&#x1f352;1.2 没有使用MyBatis时的操作流程&#x1f352;1.3 MyBatis的操作与数据库之间的流程&#x1f34e;二.创建MyBatis项目&#x1f352;2.1 idea创建&#x1f352;2.2 配…

【Git】一文带你入门Git分布式版本控制系统(撤销修改、删除文件)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

Debezium故障演练

1、搭建演练环境 postgresql及wal2json插件安装:https://blog.csdn.net/li281037846/article/details/128411222 kafka及kafka-connect安装&#xff0c;略 //添加debezium connector curl -i -X POST -H "Content-Type:application/json" -H "Accepted:applic…

Qt样式(qss)使用小结(软件换肤,比如暗黑模式)

1.背景&#xff1a; Qt style sheet&#xff08;qss&#xff09;跟前端技术一样&#xff0c;就是为了美化界面。关键是&#xff0c;太好用了。之前还为此写过一篇博客。 Qt样式&#xff08;qss&#xff09;手册小结_大橘的博客-CSDN博客 其中主要是记录如何获取手册细节。 …

6、GPIO输入按键检测(轮询检测)

目录 0x01、简介 0x02、硬件设计 0x03、编写函数 0x001、按键初始化 0x002、按键检测 0x003、按键led翻转 0x04、源程序下载地址 0x01、简介 本次实验主要实现按键控制LED灯。 由于机械按键在按下和抬起的时候会产生按键抖动&#xff0c;所以在设计的时候需要考虑如何消除抖…

Pytorch可视化特征图(代码 亲测可用)

2013年Zeiler和Fergus发表的《Visualizing and Understanding Convolutional Networks》 早期LeCun 1998年的文章《Gradient-Based Learning Applied to Document Recognition》中的一张图也非常精彩&#xff0c;个人觉得比Zeiler 2013年的文章更能给人以启发。从下图的F6特征&…

会议OA项目-首页

目录一、Flex布局简介什么是flex布局&#xff1f;flex属性学习地址&#xff1a;案例演示二、轮播图组件及mockjs三、会议OA小程序首页布局一、Flex布局简介 布局的传统解决方案&#xff0c;基于盒状模型&#xff0c;依赖 display属性 position属性 float属性 什么是flex布局…

简单有效的Mac内存清理方法,不用收藏也能记住

Mac电脑使用的时间越久&#xff0c;系统的运行就会变的越卡顿&#xff0c;这是Mac os会出现的正常现象&#xff0c;卡顿的原因主要是系统缓存文件占用了较多的磁盘空间&#xff0c;或者Mac的内存空间已满。如果你的Mac运行速度变慢&#xff0c;很有可能是因为磁盘内存被过度占用…

如何理解并记忆DataFrame中的Axis参数

当我们遇到有axis参数的方法时&#xff0c;脑子里的第一反应应该是&#xff1a;这个方法一定是沿着某一方向进行某种“聚合”或者“过滤”操作。在此场景下&#xff0c;Axis参数就是用来设定操作方向的&#xff1a;是垂直方向还是水平方向&#xff1f; axis0: 一行一行推进&…

【微服务架构实战】第1篇之API网关概述

1.网关概述 采用分布式、微服务的架构模式开发系统时&#xff0c;API 网关是整个系统中必不可少的一环。 1.1 没有网关会有什么问题&#xff1f; 在微服务架构模式下&#xff0c;1个系统会被拆分成多个微服务&#xff0c;如果每个微服务都直接暴露给调用方&#xff0c;会有以…

MySQL主键和唯一键的区别

主键和唯一键基本知识参考这篇文章 MySQL表的约束 &#xff0c;本篇文章主要是谈一谈主键和唯一键的区别从而更好的理解唯一键和主键。 在上篇文章中已经提到 主键&#xff1a; primary key 用来唯一的约束该字段里面的数据&#xff0c;不能重复&#xff0c;不能为空&#x…

vue父页面调用子页面及方法及传参,鼠标光标定位

项目场景&#xff1a; vue父页面调用子页面及方法 问题描述 vue中父界面调用子界面及方法时界面可以调用&#xff0c;但是调用方法的时候第一次报错&#xff0c;但是关掉界面再次重新打开就没问题了 原因分析&#xff1a; 在我之前添加鼠标指针定位的时候&#xff0c;如果在…

记录scoped属性的使用和引发的问题

背景 在对表格数据进行样式处理时&#xff0c;通过业务逻辑判断&#xff0c;进行对符合要求的表格填充背景色&#xff0c;没有符合预期的效果。反复排查校验代码和判断逻辑&#xff0c;都没有什么问题&#xff0c;可能还是样式上出现问题。再通过F12 选取元素对表格设置背景色时…

获取树形结构中,父节点下所有子/孙节点(递归方式)

获取树形结构中&#xff0c;父节点下所有子/孙节点&#xff08;递归方式&#xff09;1 树形结构&#xff08;TreeItem类&#xff09;2 测试代码&#xff08;main函数&#xff09;3 运行效果1 树形结构&#xff08;TreeItem类&#xff09; 这里通用型树形结构为TreeItem类&…

初学Java web(七)RequestResponse

Request&Response Request:获取请求数据 Response:设置响应数据 一.Request对象 1.Request继承体系 Tomcat需要解析请求数据&#xff0c;封装为requestx对象并且创建requestx对象传递到service方法中 使用request对象&#xff0c;查阅JavaEE API文档的HttpServletReque…

rocketMq架构原理精华分析(一)

rocketMq架构原理精华分析是我们这篇文章的核心&#xff0c;从消息中间件的对比、架构模型、消息模型、常见问题等逐一分析&#xff1a; 一、中间件对比&#xff1a; RabbitMq 集群效果不太好&#xff0c;底层不是java 语言&#xff0c;研究原理比较困难&#xff1b; Kafka是…

前端面试题之计算机网络篇 OSI七层网络参考模型

互联网数据传输原理 &#xff5c;OSI七层网络参考模型 OSI七层网络参考模型 应用层&#xff1a;产生网络流量的程序表示层&#xff1a;传输之前是否进行加密或者压缩处理会话层&#xff1a;查看会话&#xff0c;查木马 netstat-n传输层&#xff1a;可靠传输、流量控制、不可…

亿级流量的互联网项目如何快速构建?手把手教你构建思路

一. 大流量的互联网项目 1.项目背景 索尔老师之前负责的一个项目&#xff0c;业务背景是这样的。城市的基础设施建设是每个城市和地区都会涉及到的&#xff0c;如何在基建工地中实现人性化管理&#xff0c;是当前项目的主要诉求。该项目要实现如下目标&#xff1a; 工地工人的…

C语言实现http下载器(附代码)

C语言实现http的下载器。 例&#xff1a;做OTA升级功能时&#xff0c;我们能直接拿到的往往只是升级包的链接&#xff0c;需要我们自己去下载&#xff0c;这时候就需要用到http下载器。 这里分享一个&#xff1a; 功能&#xff1a; 1、支持chunked方式传输的下载 2、被重定…

Apollo开放平台8.0发布:多维升级“为开发者而生”

Apollo开放平台8.0重磅发布&#xff1a;多维升级“为开发者而生” Apollo开放平台迎来8.0版本&#xff0c;百度自动驾驶开放平台迈向易用性时代 百度Apollo EDU计划进展公布&#xff1a;已覆盖自动驾驶技术人才33.5万、700多所院校 Apollo Studio学习实践社区上线&#xff0c;新…