代码随想录第三章读书笔记——数组

news2024/12/24 9:09:00

一.二分查找

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

左必右闭写法

第一种写法,我们定义 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,如图所示:

// 版本一
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
        while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
            int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if (nums[middle] > target) {
                right = middle - 1; // target 在左区间,所以[left, middle - 1]
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,所以[middle + 1, right]
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }
};

左闭右开写法

如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right) ,那么二分法的边界处理方式则截然不同。

有如下两点:

  • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的

  • if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]

在数组:1,2,3,4,7,9,10中查找元素2,如图所示:(注意和方法一的区别

// 版本二
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
        while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
            int middle = left + ((right - left) >> 1);
            if (nums[middle] > target) {
                right = middle; // target 在左区间,在[left, middle)中
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,在[middle + 1, right)中
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }
};

二.双指针法

双指针法基本都是应用在数组,字符串与链表的题目上

例题

27. 移除元素 - 力扣(Leetcode)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间, 你必须仅使用 O(1) 额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:

给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

你不需要考虑数组中超出新长度后面的元素。

要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。

通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组

  • 慢指针:指向更新 新数组下标的位置

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
         int slow=0;//慢指针
         int length=nums.size();
         for(int fast=0;fast<length;fast++){//快指针
             if(nums[fast]!=val){
                 nums[slow]=nums[fast];
                 slow++;
             }
         }
         return slow;
    }
};

三.滑动窗口

1.1例题

209. 长度最小的子数组 - 力扣(Leetcode)

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:

输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。

提示:

  • 1 <= target <= 10^9

  • 1 <= nums.length <= 10^5

  • 1 <= nums[i] <= 10^5

解法:所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。其实滑动窗口也可以理解为双指针法的一种!只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些。

在本题中实现滑动窗口,主要确定如下三点:

  • 窗口内是什么?

  • 如何移动窗口的起始位置?

  • 如何移动窗口的结束位置?

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。

窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

解题的关键在于 窗口的起始位置如何移动

滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int i=0;
        int j=0;
        int sum=0,result=INT_MAX;
        while(j<nums.size()){
            sum+=nums[j];
            while(sum>=target){
                if(j-i+1<result)result=j-i+1;
                sum-=nums[i];//必须先减再加
                i++;
            }
            j++;
        }
        if(result==INT_MAX)return 0;
        else return result;
    }
};
  • 时间复杂度:O(n)

看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)

  • 空间复杂度:O(1)

1.2模板

关键字:满足XXX条件(计算结果,出现次数,同时包含)最长/最短 子串/子数组

例如:长度最小的子数组

//最长模板:
初始化left, right, result, bestResult
while (右指针没有到结尾) {
    窗口扩大, 加入right对应元素, 更新当前result
    while (result不满足要求) {
        窗口缩小, 移除left对应元素, left右移
    }
    更新最优结果bestResult
    right++;
}
返回bestResult;
//最短模板:
初始化left, right, result, bestResult
while (右指针没有到结尾) {
    窗口扩大, 加入right对应元素, 更新当前result
    while (result满足要求) {
        更新最优结果bestResult
        窗口缩小, 移除left对应元素, left右移
    }
    right++;
}
返回bestResult;

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

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

相关文章

FPGA的GigE Vision IP相机图像采集方案设计,转换为千兆UDP,支持10G MAC

1 概述 GigE Vision是一个比较复杂的协议&#xff0c;要在FPGA中完全实现具有较大的难度。如果FPGA作为接收端希望实现GigE Vision相机的配置和图像采集功能&#xff0c;则只需要实现其中小部分功能即可。本文对原有GigE Vision协议的结构进行了裁剪&#xff0c;仅保留设备搜索…

Maven基本使用以及IDEA中配置使用的详细介绍

文章目录MavenMaven基本介绍Maven基本使用IDEA配置MavenIDEA配置MavenMaven坐标详解IDEA创建Maven项目IDEA导入Maven项目Maven依赖管理Maven Maven基本介绍 Apache Maven 是一个项目管理和构建工具&#xff0c;它基于项目对象模型(POM)的概念&#xff0c;通过一小段描述信息来…

GAMES101学习笔记——光栅化

一&#xff1a;什么是光栅化&#xff08;Rasterization&#xff09; 把空间里的物体画在屏幕上。 屏幕由一个个阵列排布的像素点组成&#xff0c;屏幕大小指宽度方向由width个像素点&#xff0c;高度方向由height个像素点。 像素点索引范围&#xff1a;&#xff08;0&#xf…

【Java开发】JUC进阶 03:读写锁、阻塞队列、同步队列

1 读写锁&#xff08;ReadWriteLock&#xff09;&#x1f4cc; 要点实现类&#xff1a;ReentrantReadWirteLock通过读写锁实现更细粒度的控制&#xff0c;当然通过Synchronized和Lock锁也能达到目的&#xff0c;不过他们会在写入和读取操作都给加锁&#xff0c;影响性能&#x…

黑马程序员SSM框架教程之学习笔记1

P44-SpringMVC入门案例 1.在pom.xml中导入坐标springMVC与servlet 2.创建一个SpringMVC控制器类 3.创建springMVC配置文件springMvcCponfig 4.定义一个servlet容器启动配置类&#xff0c;在里面加载spring的配置 5.在pom.xml文件中配置tomcat插件 运行结果显示 P45-springMVC入…

2023-03-05:ffmpeg推送本地视频至lal流媒体服务器(以RTMP为例),请用go语言编写。

2023-03-05&#xff1a;ffmpeg推送本地视频至lal流媒体服务器&#xff08;以RTMP为例&#xff09;&#xff0c;请用go语言编写。 答案2023-03-05&#xff1a; 使用 github.com/moonfdd/ffmpeg-go 库。 先启动lal流媒体服务器软件&#xff0c;然后再执行命令&#xff1a; go…

linux通过nginx映射指定目录文件给外部访问

修改配置文件 #user www-data; #将user www-data;注掉改为root user root; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf;events {worker_connections 768;# multi_accept on; }http {### Basic Settings##sendfile on;tcp_nopush …

【C语言学习笔记】:三子棋具体步骤和代码

一、问题描述 用c语言实现三子棋。 二、基本流程 在写三子棋的代码之前&#xff0c;我们来看看实现这个游戏的逻辑&#xff1a; 1.菜单界面选择开始或者退出游戏。2.创建棋盘并初始化。3.打印棋盘。4.玩家落子(玩家输入行列坐标的方式来落子)&#xff0c;x’表示玩家落子。5…

既然有MySQL了,为什么还要有Redis?

目录专栏导读一、同样是缓存&#xff0c;用map不行吗&#xff1f;二、Redis为什么是单线程的&#xff1f;三、Redis真的是单线程的吗&#xff1f;四、Redis优缺点1、优点2、缺点五、Redis常见业务场景六、Redis常见数据类型1、String2、List3、Hash4、Set5、Zset6、BitMap7、Bi…

ESP32学习笔记01-环境搭建

本文参考博客https://blog.csdn.net/weixin_43599390/article/details/123944479 1.下载离线版本的 ESP IDF esp idf 下载地址 2.安装 esp idf 2.1应用修复,后,再下一步 2.2 2.3 2.4 2.5

跨屏设计规范

跨屏设计规范 以windows10x 为例&#xff0c;其在具体交互上&#xff0c;到底有哪些常见的交互模式和硬件要如何结合 6.1跨平台的双屏交互设计逻辑 这种那个品的设计范式&#xff0c;其实是跨平台的通用规则&#xff0c; 在很大程度上&#xff0c;这套交互逻辑是不受操作系统…

【CSS】CSS 复合选择器 ③ ( 并集选择器 | 并集选择器与后代选择器示例 )

文章目录一、并集选择器1、语法说明2、代码示例二、并集选择器与后代选择器示例1、添加注释2、HTML 结构3、后代选择器 14、后代选择器 25、并集选择器6、完整代码示例7、显示效果一、并集选择器 1、语法说明 并集选择器 可以选择 若干 基础选择器 选择出的 并集元素集合 ; 并集…

【亲测】Centos7系统非管理(root)权限编译NCNN

前言 由于使用的是集群&#xff0c;自己不具有管理员权限&#xff0c;所以以下所有的情况均在非管理员权限下进行安装&#xff0c;即该安装策略仅适用于普通用户构建自己的环境。 什么是NCNN ncnn是一款非常高效易用的深度学习推理框架&#xff0c;支持各种神经网络模型&#x…

文件异步多备常用方案

业务需求上经常存在需要对同一个文件进行双上传&#xff0c;上传到不同云存储桶&#xff0c;以防出现某一个云厂商因各种意外导致自身服务出现不可用的情况&#xff0c;当然&#xff0c;还有其他措施可以避免&#xff0c;现在只针对通过程序业务代码而双写存储的这个场景。 业务…

Java分布式解决方案(三)

文章目录&#x1f525;MySQL事务-MySQL中锁的分类&#x1f525;MySQL事务-MySQL中的死锁问题&#x1f525;MySQL事务-MySQL中锁的分类 MySQL中锁的分类 从本质上讲&#xff0c;锁是一种协调多个进程或多个线程对某一资源的访问的机制&#xff0c;MySQL使用锁和MVCC机制实现了…

了解基本的html和javascript

用记事本编辑一个文本文件&#xff0c;代码如下&#xff0c; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>my name is bo</title> <script>alert(hello); </script> </head> <body>&…

实验2 设计模式实验1

实验内容: 1. 使用简单工厂模式设计一个可以创建不同几何形状(Shape)&#xff0c;例如圆形 (Circle)、矩形(Rectangle)和三角形(Triangle)等的绘图工具类&#xff0c;每个几何图形均具 有绘制方法draw()和擦除方法erase()&#xff0c;要求在绘制不支持的几何图形时&#xff…

Android 基础知识4-3.6 ToggleButton(开关按钮)Switch(开关)详解

一、ToggleButton(开关按钮) 1.1、简介 ToggleButton 类似开关有开和关两种状态&#xff0c;不同的状态下可以有不同的文本。 public class ToggleButton extends CompoundButton Displays checked/unchecked states as a button with a "light" indicator …

CNN基础

Tip&#xff1a;仅供自己学习记录&#xff0c;酌情参考 1. 前馈与反馈神经网络 神经网络有前馈神经网络和反馈神经网络&#xff0c;前向神经网络也就是前馈神经网络。 前馈型神经网络各神经元接收前一层的输入&#xff0c;并输出给下一层&#xff0c;没有反馈。节点分为两类…

nacos-sdk-rust binding to NodeJs

广告时间 nacos-sdk-rust-binding-node : nacos-sdk-rust binding to NodeJs with napi. Tip: nacos-sdk-nodejs 仓库暂未提供 2.x gRPC 交互模式&#xff0c;为了能升级它&#xff0c;故而通过 node addon 方式调用 nacos-sdk-rust npm 包 -> https://www.npmjs.com/packa…