【算法篇】数组类(笔记)

news2024/11/25 22:43:25

目录

一、二分查找

 1. 方法一

2. 方法二

二、移除元素

1. 暴力破解

2. 双指针法

三、有序数组的平方

双指针法    

四、长度最小的子数组

 1. 暴力破解

2. 滑动窗口

五、螺旋矩阵 II


一、二分查找

704. 二分查找 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/binary-search/description/

        给定一个 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

提示:

  • 你可以假设 nums 中的所有元素是不重复的。
  • n 将在 [1, 10000]之间。
  • nums 的每个元素都将在 [-9999, 9999]之间。

 1. 方法一

        定义 target 在一个在左闭右闭的区间里,也就是 [left, right]

class Solution {
public:
    int search(vector<int>& nums, int target) {
        // 二分查找
        // 方法1 [left, right]
        int left = 0, right = nums.size() - 1;
        
        int middle = left + ((right - left) / 2);  // 防止 left + right 溢出

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

2. 方法二

        定义 target 是在一个在左闭右开的区间里,也就是 [left, right)

class Solution {
public:
    int search(vector<int>& nums, int target) {
        // 二分查找
        // 方法2 [left, right)
        int left = 0, right = nums.size();
        
        int middle = left + ((right - left) / 2);  // 防止 left + right 导致溢出
        
        while(left < right)
        {
            middle = left + ((right - left) / 2);
            if(nums[middle] > target)
            {
                right = middle;
            }
            else if(nums[middle] < target)
            {
                left = middle + 1; 
            }
            else if(nums[middle] == target)
            {
                return middle;
            }
        }
        return -1;
    }
};
  • 因为 left == right 在区间 [left, right) 是没有意义的,所以 while (left < right),这里使用 < 。
  • if (nums[middle] > target) right 更新为 middle,因为当前 nums[middle] 不等于 target,去 左区间 继续寻找,而寻找 区间是 左闭右开区间,所以 right 更新为 middle,即:下一个 查询区间不会去比较 nums[middle]。

二、移除元素

27. 移除元素 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/remove-element/description/

        给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

        不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。

        元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2,_,_]
解释:你的函数函数应该返回 k = 2, 并且 nums 中的前两个元素均为 2。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。
示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3,_,_,_]
解释:你的函数应该返回 k = 5,并且 nums 中的前五个元素为 0,0,1,3,4。
注意这五个元素可以任意顺序返回。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

1. 暴力破解

        两层 for 循环,一个 for 循环 遍历数组元素 ,第二个 for 循环更新数组。找到一个,后面的数字整体向前移一位。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int len = nums.size();

        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--;
            }
        }
        return len;
    }
};

2. 双指针法

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

        用 快指针赋值给满指针,可以实现 暴力破解中 数字整体 向前移一位的 操作。

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

三、有序数组的平方

977. 有序数组的平方 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/squares-of-a-sorted-array/description/

        给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

双指针法    

         数组是有序的, 只不过 负数平方之后 可能成为 最大数了。那么 数组平方的 最大值就在 数组的 两端,不是 最左边就是 最右边,不可能 是中间。 此时 可以考虑 双指针法,left 指向 起始位置,right 指向终止位置。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int len = nums.size() - 1;
        vector<int> result(nums.size());
        int left = 0, right = len;

        while(left <= right)
        {
            int le = nums[left] * nums[left];
            int ri = nums[right] * nums[right];
            if(le > ri)
            {
                result[len--] = le;
                left++;
            }
            else if(le <= ri)
            {
                result[len--] = ri;
                right--;
            }
        }
        return result;
    }
};

四、长度最小的子数组

209. 长度最小的子数组 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/minimum-size-subarray-sum/description/

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

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

 1. 暴力破解

         使用 两个 for 循环,然后 不断的寻找符合条件的 子序列。一个 for 循环滑动窗口的 起始位置,一个 for 循环为滑动窗口的终止位置,用两个 for 循环 完成了一个不断搜索区间的过程。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX;
        int len = nums.size();

        int pan = 0;

        for(int i = 0; i < len ; i++)
        {
            int sum = 0;
            for(int j = i; j < len; j++)
            {
                sum += nums[j];
                if(sum >= target)
                {
                    pan = j - i + 1;
                    result = result > pan ? pan : result;
                    break;
                }
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

2. 滑动窗口

        滑动窗口,就是不断的 调节 子序列的 起始位置 和 终止位置,从而 得出我们要 想的 结果滑动窗口 只用一个 for 循环,那么 这个循环的索引,一定是表示 滑动窗口的终止位置。

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

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

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

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

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        // 滑动窗口
        int result = INT32_MAX;
        int len = nums.size();
        int sum = 0;

        int j = 0;  // 窗口起始位置

        for(int i = 0; i < len; i++)
        {
            sum += nums[i];
            while(sum >= target)
            {
                int pan = i - j + 1;
                result = result > pan ? pan : result;
                sum -= nums[j++];
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

五、螺旋矩阵 II

59. 螺旋矩阵 II - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/spiral-matrix-ii/description/

        给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]

        模拟 顺时针画矩阵的 过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

        由外向 内一圈一圈 这么 画下去。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> result(n, vector<int>(n, 0));
        int take_x = 0, take_y = 0;  // 每次循环起始位置定位
        int nums = n / 2;  // 循环几次
        int mid = n / 2;  // 矩阵中心位置
        int count = 1;  // 填入的数字
        int offset = 1;   // 循环离右边界的距离
        int i, j;
        while(nums--)
        {
            i = take_x;
            j = take_y;

            // 循环一圈
            for(; j < n - offset; j++)
            {
                result[i][j] = count++;
            }
            for(; i < n - offset; i++)
            {
                result[i][j] = count++;
            }
            for(; j > take_x; --j)
            {
                result[i][j] = count++;
            }
            for(; i > take_y; --i)
            {
                result[i][j] = count++;
            }

            // 更新循环起点位置
            take_x++;
            take_y++;
            offset++;
        }

        // 奇数中间没填
        if(n % 2 != 0)
        {
            result[mid][mid] = count;
        }
        
        return result; 
    }
};

        这里每一种颜色,代表一条边,我们遍历的长度,可以看出每一个拐角处的处理规则,拐角处让给新的一条边来继续画。这也是坚持了每条边左闭右开的原则。

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

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

相关文章

深入理解Java虚拟机:Jvm总结-虚拟机字节码执行引擎

第八章 虚拟机字节码执行引擎 8.1 意义 不受物理条件制约地定制指令集与执行引擎的结构体系&#xff0c;能够执行那些不被硬件直接支持的指令集格式。输入的是字节码二进制流&#xff0c;处理过程是字节码解析执行的等效过程&#xff0c;输出的是执行结果 8.2 运行时栈帧结构…

jupyter出错ImportError: cannot import name ‘np_utils‘ from ‘keras.utils‘ ,怎么解决?

文章前言 此篇文章主要是记录一下我遇到的问题以及我是如何解决的&#xff0c;希望下次遇到类似问题可以很快解决。此外&#xff0c;也希望能帮助到大家。 遇到的问题 出错&#xff1a;ImportError: cannot import name np_utils from keras.utils &#xff0c;如图&#xf…

Metasploit Pro 4.22.3-2024081901 (Linux, Windows) - 专业渗透测试框架

Metasploit Pro 4.22.3-2024081901 (Linux, Windows) - 专业渗透测试框架 Rapid7 Penetration testing, release Aug 19, 2024 请访问原文链接&#xff1a;https://sysin.org/blog/metasploit-pro-4/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页…

SonicWall SSL VPN曝出高危漏洞,可能导致防火墙崩溃

近日&#xff0c;有黑客利用 SonicWall SonicOS 防火墙设备中的一个关键安全漏洞入侵受害者的网络。 这个不当访问控制漏洞被追踪为 CVE-2024-40766&#xff0c;影响到第 5 代、第 6 代和第 7 代防火墙。SonicWall于8月22日对其进行了修补&#xff0c;并警告称其只影响防火墙的…

代码随想录27期|Python|Day51|​动态规划|​115.不同的子序列|​583. 两个字符串的删除操作​|72. 编辑距离

115. 不同的子序列 本题是在原来匹配子序列的基础上增加了统计所匹配的子序列个数&#xff0c;也就是dp数组的定义和更新公式和原来的有所区别。 1、dp数组的定义 dp[i][j]表示以i-1和j-1为末尾的字符串中&#xff0c;给定字符串s包含目标字符串t的个数。注意这里不是长度。…

vs2019成功连接数据库mysql

②在vs2019中创建新项目&#xff0c;注意x64 ③ 右击项目打开属性 ④添加include路径 ⑤添加lib路径 点击确定后点击应用 ⑥ 点击全部确定 ⑦ ⑧启动mysql 进入数据库&#xff1a; 在数据库中创建student的表 ⑨在va2019中输入下面代码测试 注意&#xff1a;密码换成自己…

大数据Flink(一百一十六):Flink SQL的时间属性

文章目录 Flink SQL的时间属性 一、Flink 三种时间属性简介 二、Flink 三种时间属性的应用场景 三、​​​​​​​SQL 指定时间属性的两种方式 四、​​​​​​​​​​​​​​SQL 处理时间DDL定义 五、​​​​​​​​​​​​​​SQL 事件时间DDL定义 Flink SQL的时…

Nature子刊|C4平台助力单细胞多组学分析,揭秘睾丸生殖细胞瘤的分子特征

在精准医疗的大潮中&#xff0c;单细胞多组学技术正成为研究肿瘤微环境的强有力工具。最近&#xff0c;一项发表在《Nature Communications》的重磅研究&#xff0c;就利用了包括DNBelab C Series在内的平台设备&#xff0c;对睾丸生殖细胞瘤&#xff08;Seminoma&#xff09;进…

矩阵分析 学习笔记3 多项式矩阵 jordan标准型

就是说这个矩阵里面的各个元素都是多项式&#xff0c;多项式的主角是类目大&#xff08;自变量&#xff09;。 多项式矩阵的秩是啥呢&#xff1f; 0多项式就是完全0的那种&#xff0c;就一个0&#xff0c;类目大都没有了。 多项式矩阵的秩和带一个类目大进去变成普通矩阵的秩不…

最大间距问题

LeetCode164 最大间距 基数排序 #include <iostream> #include <vector> using namespace std;class Solution { public:int maximumGap(vector<int>& nums) {int nnums.size();if(n<2) return 0;int exp1;int Maxnums[0];vector<int> buf(n)…

WD mybook10T硬盘exfat变0字节恢复方法

WD的mybook系列应该全部是3.5寸台式机机械硬盘然后加了盒子做成了移动存储&#xff0c;单盘容量已经极高了&#xff0c;此类盘出厂的文件系统一般为exfat&#xff08;可能是厂商为了方便mac客户使用&#xff09;。下边这个案例就是我们经常遇到的exfat变0字节。 故障存储:WD m…

用网卡的ap模式抓嵌入式设备的网络包

嵌入式设备不像pc上&#xff0c;有一些专门的工具比如wareshark来抓包&#xff0c;嵌入式设备中&#xff0c;有的可能集成了tcpdump&#xff0c;可以用来进行简单的抓包&#xff0c;但是不方便分析&#xff0c;况且有的嵌入式设备不一定就集成了tcpdump工具。 关于tcpdump工具…

[001-03-007].第07节:Redis中的事务

我的后端学习大纲 我的Redis学习大纲 1、Redis事务是什么&#xff1a; 1.可以一次执行多个命令&#xff0c;本质是一组命令的集合。一个事务中的所有命令都会序列化&#xff0c; 按顺序地串行化执行而不会被其他命令插入&#xff0c;不许加塞2.一个队列中&#xff0c;一次性、…

AI+RPA机器人 实现自动调用 kimi 的 AI 对话功能(内附使用教程)

前言 今天尝试写一个用RPA自动调用kimi的AI对话功能。 把这个写好之后&#xff0c;就是后面其他一切AI相关的基础&#xff0c;比如自动用AI写文章啊&#xff0c;比如搭建一个微信AI机器人啊等等&#xff0c; 都能用到今天实现的AI对话功能。 话不多说&#xff0c;直接看思路…

在 Windows 中使用系统文件检查器

DiSM.exe /Online /Cleanup-image /Restorehealth

项目管理方法,方法和框架–初学者指南

项目管理方法&#xff0c;方法和框架–初学者指南 项目可以通过各种方式成功结束。但是&#xff0c;最好&#xff0c;最受欢迎的项目管理方法&#xff0c;方法和框架总是在变化。新概念无时无刻不在出现。所有成功的项目都包含一整套方法&#xff0c;工具和技术。实际上&#x…

基于SpringBoot+Vue+MySQL的考研互助交流平台

系统展示 用户前台界面 管理员后台界面 系统背景 本文设计并实现了一个基于SpringBoot、Vue.js和MySQL的考研互助交流平台。该平台旨在为广大考研学子提供一个集资源共享、学习交流、经验分享、心理辅导等功能于一体的综合性在线社区。通过SpringBoot构建高效稳定的后端服务&am…

Whistle 客户端抓包工具

Whistle 客户端 安装或更新 官网&#xff1a; 关于whistle GitBook (wproxy.org)https://wproxy.org/whistle/ Whistle 客户端目前只支持 Mac 和 Windows 系统&#xff0c;如果需要在 Linux、 Docker、服务端等其它环境使用&#xff0c;可以用命令行版本&#xff1a;GitHub…

汽车免拆诊断案例 | 沃尔沃V40 1.9TD断续工作

故障现象 一辆04款的沃尔沃V40 1.9 TD&#xff0c;发动机代码D4192T3&#xff0c;使用博世EDC15C发动机管理。客户说车子断续工作&#xff0c;怀疑是正时皮带出现问题。卸下上皮带盖&#xff0c;检查发现皮带仍然在原来的位置上并且没有出现松动。起动发动机&#xff0c;车辆能…

1 MATLAB 绘图函数函数: plot

>> t -10:0.001:10; >> x sin(t); >> plot(t,x)