当前位置: 首页 > news >正文

算法打卡day1|数组篇|Leetcode 704.二分查找、27.移除元素

数组理论基础

数组是存放在连续内存空间上的相同类型数据的集合,可以方便的通过下标索引的方式获取到下标下对应的数据。

1.数组下标都是从0开始的。

2.数组内存空间的地址是连续的。

正是因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址所以数组的元素是不能删的,只能覆盖。

在C++中二维数组在内存的空间地址是连续,但在java中并不是连续的。

java中的数组排列方式如下,所以Java的二维数组在内存中不是 3*4 的连续地址空间,而是四条连续的地址空间组成!

算法题

Leetcode 704.二分查找

题目链接:二分查找

大佬视频讲解:手把手带你撕出正确的二分法

个人思路

题目要求是用二分法;那具体步骤为:找到数组中间的值,将这个值循环与目标值对比,1.若找到目标值放回下标2.没找到目标值的话,则按照与目标值对比的大小,重新选择范围,再选择这个范围中的中间值继续对比;但这其中比较难解决的是范围的确定

解法

这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因此以后遇到此种类型都可以考虑使用二分法;

二分法中,对区间的定义很重要。区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。

二分法第一种写法:左闭右闭

即[left, right];左闭右闭要注意以下两点

  1. 循环while中的判断条件 “(left <= right) ”要使用 <= ,因为left == right是有意义的。
  2. 目标值小于中间值,右区间需要改变时;right 要赋值为 mid - 1,因为当前这个nums[middle]一定不是target。
class Solution {public int search(int[] nums, int target) {int left=0;int right=nums.length-1;//定义target在左闭右闭的区间里,[left, right]if(target <nums[0]||target>nums[right-1]){//避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算return -1;}while(left<=right){int mid=left+((right-left)>>1);//防止溢出;>> 是右移位运算符,相当于除以 2 并向下取整if(nums[mid]==target){return mid;}else if(nums[mid]<target){//target 在右区间,即[mid + 1, right]left=mid+1;}else if(nums[mid]>target){//target 在左区间,即[left, mid- 1]right=mid-1;}}return -1;}
}

时间复杂度:O(log n);(折半循环)

空间复杂度:O(1);(没有使用多余空间)

二分法第二种写法:左闭右开

即[left, right);左闭右开要注意以下两点

  1. 循环while中的判断条件“(left < right)”,这里使用 < ,因为left == right在区间[left, right)是没有意义的
  2. 目标值小于中间值,右区间需要改变时, right 更新为 mid,因为下一个查询区间不会去比较nums[middle]
class Solution {public int search(int[] nums, int target) {int left=0;int right=nums.length;//定义target在左闭右开的区间里,[left, right]if(target <nums[0]||target>nums[right-1]){//避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算return -1;}while(left<right){int mid=left+((right-left)>>1);//防止溢出;>> 是右移位运算符,相当于除以 2 并向下取整if(nums[mid]==target){return mid;}else if(nums[mid]<target){//target 在右区间,即[mid + 1, right)left=mid+1;}else if(nums[mid]>target){//target 在左区间,即[left, mid)right=mid;}}return -1;}
}

时间复杂度:O(log n);(折半循环)

空间复杂度:O(1);(没有使用多余空间)

Leetcode27.移除元素

题目链接:27.移除元素

大佬视频讲解:数组中移除元素并不容易

个人思路

因为数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖,所以若要暴力解决的话,得两次循环,一次循环找与目标值对应的,二次循环将删除元素其后面的元素向前赋值;

这种解法慢,也可以换成双指针来解决,指针分为快慢指针,快指针找需要删除的元素,慢指针找新数组的下标;

解法
暴力解法

双重循环

class Solution {public int removeElement(int[] nums, int val) {int len= nums.length;for (int i = 0; i < len; i++) {if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位for (int j = i + 1; j < len; j++) {nums[j - 1] = nums[j];}i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位len--; // 此时数组的大小-1}}return len;}
}

时间复杂度:O(n^2);(两个for循环 n*n)

空间复杂度:O(1);(没有使用多余空间)

快慢双指针

搞清楚双指针的定义非常关键,快指针的作用是寻找新数组的元素 ,新数组就是不含有目标元素的数组;慢指针的作用是指向更新 新数组下标的位置

class Solution {public int removeElement(int[] nums, int val) {int slow=0;//慢指针for(int fast=0;fast<nums.length;fast++){if(nums[fast]!=val){//如果没有找到目标元素则一起向前遍历nums[slow]=nums[fast];slow++;}}return slow;}
}

时间复杂度:O( n);(一个for循环)

空间复杂度:O(1);(没有使用多余空间)

以上是个人的思考反思与总结,若只想根据系列题刷,参考卡哥的网址代码随想录算法官网

相关文章:

  • OpenAI文生视频大模型Sora概述
  • C 标准库 - <float.h>
  • 【Ubuntu】通过网线连接两台电脑以实现局域网连接的方法
  • 【docker入门】1-
  • 【Java面试】MongoDB
  • (3)llvm ir转换过程
  • GIT中对子仓库的使用方法介绍
  • 软件测试入门(全面认识软件测试)
  • LeetCode24.两两交换链表中的节点
  • 【LNMP】云导航项目部署及环境搭建(复杂)
  • [HTML]Web前端开发技术30(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页
  • 【Django开发】0到1开发美多shop项目:用户登录模块开发。全md文档笔记(附代码 文档)
  • Python 高级语法:一切皆对象
  • 【Flink精讲】Flink任务调度机制
  • ElasticSearch语法
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • JavaScript对象详解
  • mongodb--安装和初步使用教程
  • Python_OOP
  • React的组件模式
  • Shadow DOM 内部构造及如何构建独立组件
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 计算机在识别图像时“看到”了什么?
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 以太坊客户端Geth命令参数详解
  • 怎样选择前端框架
  • raise 与 raise ... from 的区别
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • #每日一题合集#牛客JZ23-JZ33
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • $L^p$ 调和函数恒为零
  • (2)nginx 安装、启停
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (zt)最盛行的警世狂言(爆笑)
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (算法二)滑动窗口
  • .Net 4.0并行库实用性演练
  • .NET 8.0 中有哪些新的变化?
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .net core控制台应用程序初识
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .Net MVC4 上传大文件,并保存表单
  • /bin、/sbin、/usr/bin、/usr/sbin
  • @ModelAttribute注解使用
  • [20190113]四校联考
  • [Android]Android P(9) WIFI学习笔记 - 扫描 (1)
  • [AX]AX2012开发新特性-禁止表或者表字段
  • [BUG]vscode插件live server无法自动打开浏览器