代码随想录算法训练营第1天 | 数组理论基础,704. 二分查找,27. 移除元素,977.有序数组的平方

news/2025/1/8 12:16:15/文章来源:https://www.cnblogs.com/xuchiblog/p/18659472

1. 刷题部分

1.1 数组基础理论

  • 原文链接:代码随想录

1.1.1 题目内容

知识性讲解,点击链接查看原文。

1.1.2 初见想法

是一些很基本的知识,看看有么有什么生疏的。

1.1.3 看录后想法

原来有的语言的二维数组元素地址是可以行与行之间不连续的。

1.1.4 遇到的困难

暂未遇到困难。


1.2 704. 二分查找

  • 原文链接:代码随想录
  • 题目链接:704. 二分查找 - 力扣(LeetCode)

1.2.1 题目内容

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

提示:

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

1.2.2 初见想法

就是纯粹的二分查找嘛,本科的时候都学过了,写写看吧。

class Solution {
public:int search(vector<int>& nums, int target) {if(nums.size() == 0) return -1;int left = 0, right = nums.size() - 1;int mid;while (left <= right) {mid = (left + right)/2;if (nums[mid] > target) {right = mid - 1;} else if (nums[mid] < target) {left = mid + 1;}else {return mid;}}return -1;}
};

感觉挺顺的,看看录里有没有什么点是我需要补充的吧。

1.2.3 看录后想法

  • 二分查找的一个重点是边界判断
  • 不同的边界定义会导致不同的条件判断,注意整个过程边界定义应保持不变

看完之后再写一个左闭右开的版本吧:

class Solution {
public:int search(vector<int>& nums, int target) {if(nums.size() == 0) return -1;int left = 0, right = nums.size();int mid;while (left < right) {mid = (left + right)/2;if (nums[mid] > target) {right = mid;} else if (nums[mid] < target) {left = mid + 1;}else {return mid;}}return -1;}
};

1.2.4 遇到的困难

vector的一些内容有点忘记了,去网上搜了点资料复习了一下。

1.3 27. 移除元素

  • 原文链接:代码随想录
  • 题目链接:27. 移除元素 - 力扣(LeetCode)

1.3.1 题目描述

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

  • 更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
  • 返回 k

用户评测:

评测机将使用以下代码测试您的解决方案:

int[] nums = [...]; // 输入数组
int val = ...; // 要移除的值
int[] expectedNums = [...]; // 长度正确的预期答案。// 它以不等于 val 的值排序。int k = removeElement(nums, val); // 调用你的实现assert k == expectedNums.length;
sort(nums, 0, k); // 排序 nums 的前 k 个元素
for (int i = 0; i < actualLength; i++) {assert nums[i] == expectedNums[i];
}

如果所有的断言都通过,你的解决方案将会 通过

示例 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 个元素之外留下了什么并不重要(因此它们并不计入评测)。

提示:

  • 0 <= nums.length <= 100
  • 0 <= nums[i] <= 50
  • 0 <= val <= 100

1.3.2 初见想法

题目说顺序无所谓,那么直接就会想到每次遇到把末尾的非val元素移动过来好了。之前应该是写什么东西的时候有过类似的思想。

class Solution {
public:int removeElement(vector<int>& nums, int val) {for (int i = 0; i < nums.size(); i++) {//先保证末尾的元素不是valwhile (nums[nums.size() - 1] == val) {nums.pop_back();//考虑直接整个删没了的特殊情况if (nums.size() == 0) {return 0;}}//从后往前删把当前操作元素都删了那直接结束了if (i == nums.size()) {break;}//开始将末尾元素移动并替换待删元素if(nums[i] == val){nums[i] = nums[nums.size() - 1];nums.pop_back();}}return nums.size();}
};

1.3.3 看录后想法

原来快慢指针可以这么方便地解决这个问题,学到了!

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

录里还有暴力解法,说是可以锻炼一下代码实现能力,好吧,那我就听话也写一遍:

class Solution {
public:int removeElement(vector<int>& nums, int val) {//暴力解法int val_count = 0;for (int i = 0; i < nums.size(); i++) {if (nums[i] == val) {//遇到val之后把后面所有元素前移1位,在末尾就退出循环if (i == (nums.size() - 1 -val_count)) {val_count++;break;}for(int j = i + 1; j < nums.size() - val_count; j++) {nums[j - 1] = nums[j];}val_count++;//移动之后要会退i,防止连续val的情况i--;}}return nums.size() - val_count;}
};

跟录里的暴力代码比对一下,发现录里的没有写 i 到末尾的时候的判断,分析了一下确实不需要写,因为如果删最后一个元素的时候,不会进入移动元素的那个 for 循环,因而不会出现溢出。

1.3.4 遇到的困难

第一遍写我的方法时总是少考虑一些边界情况导致判题不通过,好在这些情况简单分析一下就知道怎么回事儿了。不过如果能够在判错之前就考虑好这些情况会更好,我还是需要多提高一下。

另外,在写暴力的时候发现自己确实暴露出一些代码的细节把握的不好的问题,可见暴力有时候也是有用的。

1.4 977.有序数组的平方

  • 原文链接:代码随想录
  • 题目链接:977. 有序数组的平方 - 力扣(LeetCode)

1.4.1 题目描述

给你一个按 非递减顺序 排序的整数数组 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]

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 已按 非递减顺序 排序

进阶:

  • 请你设计时间复杂度为 O(n) 的算法解决本问题

1.4.2 初见想法

先把各元素平方,然后左右两端进行比较,开一个新数组然后依次从大到小放进去。放的顺序是从后往前,这样新数组就是从小到大的了。写一下:

class Solution {
public:vector<int> sortedSquares(vector<int>& nums) {int left = 0, right = nums.size() - 1;vector<int> result(nums.size(), -1);int index = nums.size() - 1;while(left <= right){if(abs(nums[left]) <= abs(nums[right])){result[index--] = sqr(nums[right--]);}else{result[index--] = sqr(nums[left++]);}}return result;}//求绝对值int abs(int a){if(a < 0) return -a;else return a;}//求平方int sqr(int a){return a * a;}
};

1.4.3 看录后想法

与录基本一致。没有太多想法。

1.4.4 遇到的困难

无。

2. 总结部分

第一天整体来看还是比较简单的,也可能是这些数组的知识自己平时就用的比较多,所以比较熟练。后面做起来体感肯定是比今天要难的,加油吧!

学习时长:约3小时。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux使用dmidecode来查看机器有几根内存插槽,哪个槽上有内存

直接输入dmidecode即可,输出有很多,好像是根据SM总线来查询的,包括能查询到BIOS的地址空间和其中的信息等等,内存信息只是其中的一部分。摘录如下: dmidecode -t memory从这段输出可以看出,第一个Physical Memory Array是总体的内存信息,从这里可以看到有四个内存插槽、…

告别混乱!电商新年团队协作工具助你轻松应战

新年期间电商团队面临着巨大的工作量,而看板软件凭借其任务的可视化与分配、进度的实时跟踪与更新、沟通与协作的强化、个性化与定制化的满足以及多平台支持与便捷的移动办公等功能,成为了团队高效协作与沟通的得力助手,确保了电商业务在新年期间的平稳运行。看板软件凭借其…

整车电性能测试服务及设备开发

随着车辆电气化程度越来越高,整车电气系统面对更加严苛的工作环境,如何保障整车的电气可靠性越来越得到主机厂的关注。整车电性能测试是汽车电气系统开发过程中的一个关键环节,经纬恒润结合多年的整车电气工程经验,深度分解“整车-系统-子系统-部件-信号”等多个级别的性能…

springboot+shardingsphere实现读写分离和分表

参考:https://blog.csdn.net/weixin_44606481/article/details/140955787 前提:数据库配置了主从数据同步 1、依赖 <dependencies><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boo…

uniapp 荣耀手机 没有检测到设备 运行到Android手机 真机运行

背景: 使用uniapp框架搭建的项目,开发的时候在浏览器运行,因为项目要打包成App,所以需要真机联调,需要运行到Android手机,在手机上查看/运行项目。通过真机调试才能确保软件开发的准确性和页面显示的完整性。操作步骤:1.Usb连接手机和电脑,电脑上的HbuilderX打开项目;…

DC-5 靶场通关小记

rustscan端口扫描指纹识别、LFI漏洞+文件包含(nginx日志)GetShell、screen-4.5.0提权地址 https://www.vulnhub.com/entry/dc-5,314/环境配置 有兼容性问题参考 https://www.cnblogs.com/lrui1/p/18655388 信息收集 ./rustscan -a 192.168.74.130 -- -A -sC Open 192.168.74.13…

ABB IRB5500喷涂机械手维修细节查看

ABB IRB5500喷涂机器人的控制柜常见故障表现形式主要包括以下几种:1、控制柜不能启动:可能原因包括电源故障、控制电路板损坏、保险丝烧断等。处理方法包括检查电源是否正常、控制电路板是否有损坏迹象、保险丝是否烧断等。 2、abb涂装机械手控制柜报错或异常:可能原因包括…

新年新机遇:跨境电商选品策略大揭秘

跨境电商在进行新年选品时,需要综合考虑市场调研、竞争对手分析、品牌选择、价格定位、物流考虑、汇率研究、多元化产品线以及节日和特殊事件等多个因素。通过精心策划和准备,可以确保所选产品在新年期间取得良好的销售业绩。在进行跨境电商新年选品时,需要考虑多个因素以确…

年度重磅 |《2024华为开发者宝典》免费下载,多维度解读华为根生态技术

摘要:20多位华为云DTSE专家打造,10+技术领域全覆盖,图文干货+视频讲解,多维度解读华为根生态技术,拥抱技术变革,开启创新之旅。 一年一度!大家最期待的华为开发者宝典新鲜出炉!在刚刚过去的2024年,华为云开发者联盟通过25场精彩的DTSE Tech Talk直播活动,为广大开发者…

WPF页面中将一个控件的宽度绑定到其父级用户控件的实际宽度

通常情况下,使用相对宽度(如 * 星号单位)和适当的 HorizontalAlignment 是最简单有效的方法,可以确保子控件随着父控件的大小变化而自动调整。如果需要更精确的控制,可以考虑使用 RelativeSource 绑定或其他高级技术。确保父容器也支持子控件的动态尺寸调整非常重要。该实…

Windows 系统下 Docker 和 Docker Compose 安装配置:一键部署有来开源项目本地环境

在 Windows 系统上安装 Docker 和 Docker Compose,实现一键部署有来开源项目的本地环境,包括单体应用和微服务架构。🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🍃 vue-uniapp-template 🌺 仓库主页: GitCod…

Openfiler iscsi共享存储连接访问配置

Openfiler、iscsi案例说明: 通过openfiler虚拟机模拟iscsi server建立存储共享,测试多路径(multipath)配置。 测试架构:iscsi server网络配置:一、通过firefox浏览器访问openfiler服务配置 1、连接服务配置失败2、修改TLS认证级别3、连接访问openfiler配置服务二、配置op…