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

网站建实例网上建立公司网站

网站建实例,网上建立公司网站,网站seo站长工具,筑龙网官网首页文章目录写在前面习题我的想法暴力解法双指针写在前面 本节对应代码随想录中:代码随想录 习题 题目链接: 27. 移除元素- 力扣(LeetCode) 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素&a…

文章目录

    • 写在前面
    • 习题
    • 我的想法
    • 暴力解法
    • 双指针

写在前面

本节对应代码随想录中:代码随想录

习题

题目链接: 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 循环从头遍历 nums,并用 res 记录最终结果初始为0。如果当前遍历到的值等于 val,则让 res 位置和遍历到的 val 所在位置替换下,这样一轮 for 循环后前 res 位置都是 val。

新的长度用总长度减去 res 即可。而由于题目要求 nums 前 res 个要返回非 val 的数值,因此还要一轮 for 循环将前 res 个元素和后 res 个元素替换。

class Solution {public:int removeElement(vector<int>& nums, int val) {int n = nums.size(), res = 0, temp;for (int i = 0; i < n; i++) {if (nums[i] == val) {// 如果和val相等则和让当前值和前面的值替换temp = nums[i];nums[i] = nums[res];nums[res] = temp;res++;}}// 把和val相等的几个值放到后面for (int i = 0; i < res; i++) {temp = nums[i];nums[i] = nums[n - i - 1];nums[n - i - 1] = temp;}return n - res;}
};

后来看了题解后,想了下发现前 res 个可以直接删除而不用和后面 res 个替换

nums.erase(nums.begin(), nums.begin() + res);

暴力解法

两层 for 循环,第一层循环从头遍历数组,如果遇到和 val 相等的值,则用第二层 for 循环将当前位置之后的元素都像前移动一位。

例如 0 1 2 3 2 5,val=2

  • 第一层 for 循环从左到右遍历,遇到 nums[2]=2时,将后面的 3 2 5向前移一位变成0 1 3 2 5
  • 接着继续遍历(3 2 5),遇到第二个2时,将后面的5向前移一位变成0 1 3 5

题目中说了不用考虑超过新长度范围外的元素

代码如下:

需要注意的是向前移动一位后,i 要减1,如上面的例子,nums[2]=2,移动后变成0 1 3 2 5,此时若不减1下一次 i=3,将会跳过3与 val 的比较而是比较第二个2与 val。同时 size 减一方便记录新数组的长度。

// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
class Solution {
public:int removeElement(vector<int>& nums, int val) {int size = nums.size();for (int i = 0; i < size; i++) {if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位for (int j = i + 1; j < size; j++) {nums[j - 1] = nums[j];}i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位size--; // 此时数组的大小-1}}return size;}
};

与我自己想的解法相比,这个解法在找到 val 时将后面的元素向前移动一位,从而保证前面的元素都是题目要求的。

而我的解法是将找到的 val 放到前面,之后再把他们放到后面(直接放到后面会覆盖后面的元素)。

双指针

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

快指针从头遍历元素指向当前将要处理的元素,慢指针指向下一个将要赋值的位置。

  • 如果快指针指向的元素不等于 val,它一定是输出数组的一个元素,我们就将快指针指向的元素复制到慢指针位置,然后将两个指针同时右移;
  • 如果快指针指向的元素等于 val,它不能在输出数组里,此时慢指针不动,快指针右移一位。

这样左边的元素都不等于 val

与前面的两个解法相比,用慢指针替代了前面的第二个 for 循环。关键语句是 nums[slowIndex++] = nums[fastIndex]; 将后面的值直接复制到前面合适的位置。

// 时间复杂度:O(n)
// 空间复杂度:O(1)
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;}
};

这里的快指针相当于常写的 for (int i = 0; i < size; i++) 中的 i 一样,遇到和 val 相等的值时,再用一个慢指针将和 val 相等的值移到前面。如果将 fastIndex 改成常写的 i 就会发现其实就是用 nums[slowIndex++] = nums[fastIndex]; 解决了上面两种解法好几行才能解决的问题。

class Solution {
public:int removeElement(vector<int>& nums, int val) {int slowIndex = 0;for (int i = 0; i < nums.size(); i++) {if (nums[i] != val) {nums[slowIndex++] = nums[i];}}return slowIndex;}
};

总结:

  • 我的想法遇到和 val 相等的元素先替换到前面再替换到后面
  • 暴力解法遇到 val 相等的元素时,将后面的元素都向前移一位
  • 双指针遇到 val 相等的元素时,用慢指针将后面的非 val 元素替换到前面的合适位置
http://www.yayakq.cn/news/987219/

相关文章:

  • 公司怎么制作网站库尔勒网站商城建设
  • 如皋网站建设招标杭州余杭网站建设
  • 网站建设步骤wordpress优化搜索
  • 铁岭做网站的wordpress获取指定分类文章
  • 计算机基础网站建设和网络安全网页设计字体颜色代码
  • 新网站 被百度收录微商城新零售app
  • 天津企业网站制作公司wordpress删除无分类文章
  • 昆明云南微网站建设app外包公司大全
  • 广州网站制作公司优化php 读取网站文件
  • 微山建设局网站公司logo图片
  • 类似58同城的网站怎么做php做网站好吗
  • 湖州建设局新网站中国宁波网手机首页
  • 设计师网站十大网站推荐东莞市建网站
  • 电商网站优化方案分站式二手车网站源码
  • 网站怎么做移动图片不显示不出来网页游戏网站建设
  • 公司网站定制开发织梦网站普通地图插件
  • 网站的建设宗旨北京搬家公司口碑排行电话
  • 蚌埠做网站的公司景安备案网站
  • 郑州网站建设公司 艾特wordpress网站打开很慢
  • 莱州网站建设公司电话如何做网站互链规则
  • 网站排名点击谷歌外贸网站seo怎么做
  • 做网站需要些什么资料徐州高端网站建设
  • 网站建设套用模板类的要多少钱剑网三奇遇查询网站怎么做
  • 做网站的价格贵吗广州网站建设技术
  • 济源网站建设价格食品包装设计说明书
  • 可以做动画的网站都有哪些软件下载电脑ps软件
  • 一站式发稿平台专业从事网站开发公司
  • 县城做信息网站赚不赚钱中企动力是干什么的
  • 网页平面设计模板南宁百度seo推广
  • 自己制作的网站上传到服务器后怎么原来的网页没有变凤岗东莞网站建设