leetcode官方《初级算法》题集(一)数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode官方《初级算法》题集(一)数组相关的知识,希望对你有一定的参考价值。

参考技术A 由于同一个数字在两个数组中都可能出现多次,因此需要用哈希表存储每个数字出现的次数。对于一个数字,其在交集中出现的次数等于该数字在两个数组中出现次数的最小值。

首先遍历第一个数组,并在哈希表中记录第一个数组中的每个数字以及对应出现的次数,然后遍历第二个数组,对于第二个数组中的每个数字,如果在哈希表中存在这个数字,则将该数字添加到答案,并减少哈希表中该数字出现的次数。

为了降低空间复杂度,首先遍历较短的数组并在哈希表中记录每个数字以及对应出现的次数,然后遍历较长的数组得到交集。

如果两个数组是有序的,则可以使用双指针的方法得到两个数组的交集。

首先对两个数组进行排序,然后使用两个指针遍历两个数组。

初始时,两个指针分别指向两个数组的头部。每次比较两个指针指向的两个数组中的数字,如果两个数字不相等,则将指向较小数字的指针右移一位,如果两个数字相等,将该数字添加到答案,并将两个指针都右移一位。当至少有一个指针超出数组范围时,遍历结束。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

最容易想到的方法是枚举数组中的每一个数 x,寻找数组中是否存在 target - x。

当我们使用遍历整个数组的方式寻找 target - x 时,需要注意到每一个位于 x 之前的元素都已经和 x 匹配过,因此不需要再进行匹配。而每一个元素不能被使用两次,所以我们只需要在 x 后面的元素中寻找 target - x。

注意到方法一的时间复杂度较高的原因是寻找 target - x 的时间复杂度过高。因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找出它的索引。

使用哈希表,可以将寻找 target - x 的时间复杂度降低到从 O(N)O(N) 降低到 O(1)O(1)。

这样我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。

将数组排序生成2个链表,两个指针一个从头部开始遍历,一个从尾部开始遍历,相等输出,不相等移动其中一个指针。(提前指定以哪个为基)

遍历数组中的每个数字,如果集合中没有该数字,则将该数字加入集合,如果集合中已经有该数字,则将该数字从集合中删除,最后剩下的数字就是只出现一次的数字。

遍历数组即可得到每个数字出现的次数,并更新哈希表,最后遍历哈希表,得到只出现一次的数字。

由于集合保证元素无重复,因此计算集合中的所有元素之和的两倍,即为每个元素出现两次的情况下的元素之和。由于数组中只有一个元素出现一次,其余元素都出现两次,因此用集合中的元素之和的两倍减去数组中的元素之和,剩下的数就是数组中只出现一次的数字。

数组中的全部元素的异或运算结果即为数组中只出现一次的数字

我们可以使用额外的数组来将每个元素放至正确的位置。用 nn 表示数组的长度,我们遍历原数组,将原数组下标为 ii 的元素放至新数组下标为 (i+k)\bmod n(i+k)modn 的位置,最后将新数组拷贝至原数组即可。

力扣:初级算法——26. 删除排序数组中的重复项

题目:

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array

示例1:

给定数组 nums = [1,1,2],

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。


示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

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

 1 class Solution {
 2 public:
 3     int removeDuplicates(vector<int>& nums) {
 4         if(nums.size()<=1)  return nums.size();
 5         int len=nums.size();
 6         int i,j=1;
 7         int count=0;
 8         for(i=0;i<len;i++){
 9             while(j<len&&(nums[j]==nums[i])){
10                 j++;
11             }
12             if(j<len){                  //判断j是否超出范围
13                 nums[i+1]=nums[j];      //遇到不同的直接替换
14                 count++;
15             }
16         }
17         return count+1;
18     }
19 };

稍微修改一下,思路是一样的,这样更好看一些:

 1 class Solution {
 2 public:
 3     int removeDuplicates(vector<int>& nums) {
 4         if(nums.size()<=1)  return nums.size();
 5         int len=nums.size();
 6         int i=0,j=0; 7         while(j<len){
 8             if(nums[i]!=nums[j]){
 9                 nums[++i]=nums[j];
10             }
11             j++;
12         }
13         return i+1;
14     }
15 };

 

以上是关于leetcode官方《初级算法》题集(一)数组的主要内容,如果未能解决你的问题,请参考以下文章

leetcode初级算法(数组)——从数组中删除重复项

数据结构和算法LeetCode,初级算法-6两个数组的交集 II

数据结构和算法LeetCode,初级算法-6两个数组的交集 II

数据结构和算法LeetCode,初级算法-删除排序数组中的重复项

力扣:初级算法——26. 删除排序数组中的重复项

<LeetCode天梯>Day035 合并两个有序数组(切片法) | 初级算法 | Python