- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
关键词:LeetCode,力扣,题解,算法,算法题,解析,C++, Java, Python,数组,重复数字,442
题目地址:https://leetcode-cn.com/problems/find-all-duplicates-in-an-array/open in new window
给你一个长度为 n
的整数数组 nums
,其中 nums
的所有整数都在范围 [1, n]
内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。
你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题。
示例1:
输入:nums = [4,3,2,7,8,2,3,1]
输出:[2,3]
示例2:
输入:nums = [1,1,2]
输出:[1]
示例3:
输入:nums = [1]
输出:[]
提示:
1、 n==nums.length
;
2、 1<=n<=10^5
;
3、 1<=nums[i]<=n
;
4、 nums
中的每个元素出现一次或两次;
题目让找出数组中出现两次的数字。要求时间复杂度是 O(N),空间复杂度是 O(1)。
条件:
遇到这个题,你的第一思路是什么呢?
我想一定是使用 set
或者 hashmap
保存已经出现过的数字、或者数字出现的次数。
但这就不符合题目的空间复杂度是 O(1),即不使用额外空间的限制条件。
我的第二个思路是对数组排序,排序后相同的数字会相邻。可是排序的时间复杂度是 O(N∗log(N))不符合题目的时间复杂度O(N)。
所以,只能祭出大杀器:「原地修改数组」了。
其实这个思路是沿着 hashmap
的思路演化出来的,只要遇到过一次就学会了。
我们注意题目给出的条件:
我们知道一个数组有 下标
和 值
两个概念,根据下标
获取到值
。
本题中,数组中数字的取值范围 [1,n],正好与下标的范围 [0,n−1]对应。
因此,就有一个思路,对于 nums[i]
,我们将下标 =nums[i]−1的位置的数字进行映射(还要能映射回去)。
映射方法通常有两种:
动画图解如下:
对应的图如下,可以逐一观看:
Python 语言的代码如下:
class Solution(object):
def findDuplicates(self, nums):
ans = []
for num in nums:
if nums[abs(num) - 1] < 0:
ans.append(abs(num))
nums[abs(num) - 1] *= - 1
return ans
1 2 3 4 5 6 7 8
C++语言的代码如下:
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
const int N = nums.size();
vector<int> res;
for (int i = 0; i < N; i++) {
if (nums[abs(nums[i]) - 1] < 0)
res.push_back(abs(nums[i]));
nums[abs(nums[i]) - 1] *= -1;
}
return res;
}
};
1 2 3 4 5 6 7 8 9 10 11 12 13
Java 语言的代码如下:
class Solution {
public List<Integer> findDuplicates(int[] nums) {
List<Integer> res = new ArrayList<>();
for (int num : nums) {
if (nums[Math.abs(num) - 1] < 0) {
res.add(Math.abs(num));
} else {
nums[Math.abs(num) - 1] *= -1;
}
}
return res;
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13
除了取反之外,我们还可以增加一个偏移量,只要映射后与原数组的范围区分开就行。
思路和取反一样,只是为了映射后与映射前的数组不混淆。
比如,本题中数字的范围是 [1,105],我们可以增加一个偏移量 105,即映射到了一个新的数组空间。
做法:
Python 语言的代码如下:
class Solution(object):
def findDuplicates(self, nums):
res = []
for num in nums:
if nums[(num % 100000) - 1] > 100000:
res.append(num % 100000)
else:
nums[(num % 100000) - 1] += 100000
return res
1 2 3 4 5 6 7 8 9
C++语言的代码如下:
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
for (int num : nums) {
if (nums[(num % 100000) - 1] > 100000) {
res.push_back(num % 100000);
}
nums[(num % 100000) - 1] += 100000;
}
return res;
}
};
1 2 3 4 5 6 7 8 9 10 11 12 13
Java 语言的代码如下:
class Solution {
public List<Integer> findDuplicates(int[] nums) {
List<Integer> res = new ArrayList<>();
for (int num : nums) {
if (nums[(num % 100000) - 1] > 100000) {
res.add(num % 100000);
} else {
nums[(num % 100000) - 1] += 100000;
}
}
return res;
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13
1、 这个题是技巧题目,看懂了我的题解以后,以后遇到同样的题目,应该就会了;
DDKK.COM 弟弟快看-教程,程序员编程资料站,版权归原作者所有
本文经作者:负雪明烛 授权发布,任何组织或个人未经作者授权不得转发
我有一个 合作伙伴集合,我正在使用 pymongo 来检索数据 当我使用 MongoDB 查询集合时,我看到以下结果 db.partner.find({'unique_key': 'c89dbe313
嗨,我正在尝试在一个 find 命令中查找所有 js 和 css 文件。我尝试了以下所有方法但徒劳无功: find WebContent -name "*.[jc]ss?" find WebConte
我使用以下 find 命令查找并显示所有具有输入文本模式的文件。 找 。 -type f -print|xargs grep -n "模式" 我有很多项目文件夹,每个文件夹都有自己的名为“Makefi
我在Windows环境中使用Gnuwin32二进制文件。 当我想查找某种类型的文件时(例如PDF),我通常运行: find . -iname '*.pdf' -print 这在任何UNIX系统上均可完
我使用的是 Julia 编程语言,我知道你可以通过以下方式使用 find 函数: a = [ 1 2 3 4 3 5 3 6 7 8 9 3 ] find(a .== 3) 它将返回:3,5,7,12
jsperf's link 我不是 jQuery 专家(甚至不是一个好的用户),我没有研究它的整个源代码(只有一小部分不能帮助我解决这个问题)。 有人可以为我解释一下吗? 最佳答案 这个: $p.fi
我应该如何在 CentOS 7 中修复这个错误? [jalal@goku HW4]$ git clone https://github.com/pathak22/pyflow.git Cloning
是否可以更改传递给 find 中的 exec 的参数?例如,我需要以不同的名称复制文件:*.txt -> *.new.txt现在我正在为两个命令执行此操作: find /root/test -name
我想通过cleartool find 命令找到*.cs 和*.cpp 文件。但它失败了。 cleartool find "M:\test_view\code" -name "*.cs *.cpp"
我正在使用 PyMongo,看到有人建议使用 find()[:] 而不是 find()。很好奇有什么区别? 最佳答案 [:] 制作列表的浅拷贝,因此对对象的引用是相同的。我查看了 Pymongo 文档
我正在处理文件和目录,以在每个目录中查找最近修改的文件。我的代码可以工作,但作为 Ruby 的新手,我无法正确处理错误。 我使用 Find.find 获取递归目录列表,为每个目录调用我自己的函数 ne
/usr/bin/ld: cannot find -ldlib /usr/bin/ld: cannot find -lcblas /usr/bin/ld: cannot find -llapack 在
我有一些数据文件的一系列索引文件,它们基本上采用这种格式 索引文件:asdfg.log.1234.2345.index 数据文件:asdfg.log 这个想法是搜索所有索引文件。如果值 XXXX 出现
我有一个 find我运行以查找名称包含 foo 的文件的命令. 我想跳过 .git目录。下面的命令有效 除了 它打印一个 烦人 .git任何时候它跳过 .git目录: find . ( -name .
我有以下想做的事情: find . -maxdepth 6 \( -name \*.tar.gz -o -name bediskmodel -o -name src -o -name ciao -o
当我在表中查找隐藏字段时,我看到了两个隐藏字段。但是,我想通过 ID 进一步细化这两个字段。我注意到,当我使用“包含”在整个表上使用 find 时,我得到了 2 个字段。但是,如果我对隐藏字段的查找结
我正在使用下面的命令生成文件列表及其 m5sum。问题是某些文件或文件夹的名称中有空格。我将如何处理这些? find -type f -name \* | xargs md5sum 最佳答案 尝试:
我正在使用下面的命令生成文件列表及其 m5sum。问题是某些文件或文件夹的名称中有空格。我将如何处理这些? find -type f -name \* | xargs md5sum 最佳答案 尝试:
我有一个使用正则表达式查找文件的脚本。代码如下: find $dir | grep "$regex" 脚本运行有点慢,我想优化一下。搜索需要一些时间来执行,我想从中获得更好的性能。我试过这种尝试: f
这令人沮丧。我认为问题出在 api 响应返回的对象上。也许它是在字符串中,所以我所做的就是复制“postman”的响应并将其直接粘贴到js上。这样我就可以确定它在对象/数组中。但结果还是同样的错误。
我是一名优秀的程序员,十分优秀!