首页 > 编程语言 >算法入门-数组2

算法入门-数组2

时间:2024-07-16 19:28:06浏览次数:9  
标签:digits 入门 nums int 元素 height 算法 数组

第一部分:数组

26.删除有序数组中的重复项(简单)

题目:给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。

  • 返回 k

示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

第一种思路:

首先我最先想到使用Set集合,因为他的无序不重复性可以实现重复元素的删除操作,但是也是因为其无序性,如果只是简单地使用HashSet集合来实现,经过运行以后发现有部分案例无法通过,如下面的案例:

输入nums =[-3,-1,0,0,0,3,3]
​
输出:[-1,0,-3,3]
​
预期结果:[-3,-1,0,3]

究其原因,就是其无序性导致的,在Java中,HashSet是无序的数据结构,因此在使用HashSet对元素去重后,元素的顺序不会保持原先数组中的顺序。理由是,在HashSet或HashMap等集合类中,元素的存储并不是简单地按元素的大小来排列的,而是通过哈希函数将元素映射到对应的存储位置。

因此,虽然从数值本身来说-1比-3要大,但是在哈希集合中具体存储的位置并不一定按这个大小顺序排列。哈希集合是根据哈希函数的计算结果来确定元素的存储位置的,而不是根据元素大小来排序的。

但是,在此基础上,可以使用LInkedHashSet,他可以实现按照插入时的顺序存储元素。LinkedHashSet底层使用LinkedHashMap实现,它通过双向链表维护元素的插入顺序,因此可以保持元素的插入顺序,不会改变元素在集合中的顺序。

当然,这种思路不费脑力,但是方案确实不太好(复杂度太高了)~~

class Solution {
    public int removeDuplicates(int[] nums) {
        LinkedHashSet<Integer> mySet = new LinkedHashSet<>();
        for(int num : nums)
            mySet.add(num);
        int i = 0;
        for(Integer num : mySet)
            nums[i++]=num;
        return mySet.size();
    }
}

第二种思路:

想到昨天的数组题目,那么可不可以使用指针完成呢,简单作一下草图,发现完全可以行得通,不仅只需要遍历一遍数组,还不需要创建额外的空间。

首先创建两个指针,一个指针p1用来指向存储保留的元素,一个指针p2用来遍历数组中的每个元素。

初始时,两个指针p1,p2都指向下标为0的数组元素,然后在循环中,p2不断后移,然后有两种情况:

  • 如果p2指向的元素与p1指向的元素相同,则不进行任何操作,然后p2继续后移

  • 如果p2指向的元素与p1指向的元素不同,则p1后移一个单位,然后将现在p2指向的元素赋值给p1,然后p2再后移

之后重复循环,因为p2总是在p1之后(只有初始时相同),所以循环的条件是p2小于数组的长度。

PS:昨天学到的今天就想到还用上了还是很高兴的

标签:digits,入门,nums,int,元素,height,算法,数组
From: https://blog.csdn.net/qq_74742024/article/details/140470131

相关文章

  • Elastic的Kibana-8.13.4的控制台开发简单入门
    1.创建索引        在Elasticsearch中,创建索引的基本语法格式为:PUT/索引名称{ "settings":{  //索引的设置,如分片数量、副本数量、分词器等 }, "mappings":{  "properties":{   "字段名称":{    "type":"字段类型",//......
  • 代码随想录算法训练营第十四天 | 226.翻转二叉树、101. 对称二叉树、 104.二叉树的最
    226.翻转二叉树题目:.-力扣(LeetCode)思路:前序遍历代码:classSolution{public:TreeNode*invertTree(TreeNode*root){if(root!=NULL){swap(root->left,root->right);invertTree(root->left);invertTree(root->right);}......
  • 代码随想录算法训练营第十一天 | 150. 逆波兰表达式求值、 239. 滑动窗口最大值、347.
    150.逆波兰表达式求值题目:.-力扣(LeetCode)思路:遇到数字进栈,遇到符号出栈运算。代码:classSolution{public:intevalRPN(vector<string>&tokens){stack<longlong>sta;for(strings:tokens){if(s=="+"||s=="-"||s=="*"......
  • 代码随想录算法训练营第九天 | 151.翻转字符串里的单词、卡码网:55.右旋转字符串、28.
    151.翻转字符串里的单词题目:.-力扣(LeetCode)思路:用快慢双指针重置空格,先整体翻转再局部翻转代码:classSolution{public:voidremoveSpace(string&s){intslow=0;for(intfast=0;fast<s.size();fast++){if(slow!=0&&s[fast]!='')......
  • 代码随想录算法训练营第八天 | 344.反转字符串、541. 反转字符串II、卡码网:54.替换数
    344.反转字符串题目:.-力扣(LeetCode)思路:用swap遍历一个循环就行了。代码:classSolution{public:voidreverseString(vector<char>&s){for(inti=0;i<s.size()/2;++i){swap(s[i],s[s.size()-i-1]);}}};541.反转字符串II题目:.-力扣(L......
  • STM32入门教程:智能洗衣机控制
    智能洗衣机是目前流行的智能家居设备之一,它能够自动完成洗衣过程,并且能够根据衣物的种类和数量进行智能调整。在本教程中,我们将使用STM32微控制器来实现一个简单的智能洗衣机控制系统。硬件准备首先,我们需要准备以下硬件材料:STM32开发板(如STM32F407Discovery)液晶显示器(LCD)......
  • Springboot Study-入门&配置
    SpringbootStudy入门&配置1.入门构建了Springboot工程,创建springboot项目,完成了第一个项目helloworld2.配置2.1配置分类:properties>yml>yaml(优先级)2.2yaml基本语法:大小写敏感,数值前要有空格,空格缩进表示层级关系数据格式:*对象*数组(使用“-”表示数组每个元......
  • 智能算法(一)——基本粒子群算法
    基本粒子群算法原理1.算法概述2.算法步骤3.算法特点4.参数优化5.改进与优化6.应用领域7.举例1)Rosenbrock函数2.基本粒子群算法寻找最优值代码3.代码运行的结果:1.算法概述粒子群算法通过模拟一群粒子(代表潜在的解)在解空间中的运动来寻找最优解。每个粒子都具......
  • C++(函数参数为数组与指针算术)
    目录1.函数参数为数组2.指针算术2.1arr是指向第一个元素的地址2.2arr[i]表示什么?#include<iostream>voidprintArray(intarr[],intsize){for(inti=0;i<size;++i){std::cout<<arr[i]<<"";}}intmain(){intarr[5]......
  • 「代码随想录算法训练营」第十二天 | 二叉树 part2
    226.翻转二叉树题目链接:https://leetcode.cn/problems/invert-binary-tree/题目难度:简单文章讲解:https://programmercarl.com/0226.翻转二叉树.html视频讲解:https://www.bilibili.com/video/BV1sP4y1f7q7题目状态:通过个人思路:类似二叉树的层序遍历的变形,创建一个队列,先......