题目链接
英文链接:https://leetcode.com/problems/set-mismatch/
中文链接:https://leetcode-cn.com/problems/set-mismatch/
题目详述
集合 S 包含从1到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复。
给定一个数组 nums 代表了集合 S 发生错误后的结果。你的任务是首先寻找到重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例 1:
1 | 输入: nums = [1,2,2,4] |
注意:
- 给定数组的长度范围是 [2, 10000]。
- 给定的数组是无序的。
题目详解
- 创建一个
boolean数组vis,用来记录1~n的数是否出现过。 - 遍历数组,将
vis对应位置设置为true,代表出现过。 - 若在遍历过程中,发现
vis对应位置已经为true,说明此元素重复出现。 - 最后遍历
vis数组,为false的位置表示丢失的那个数。 - 时间复杂度为
O(n)。 - 空间复杂度为
O(n)。
1 | public class LeetCode_00645 { |
- 遍历数组,将元素映射到的位置的元素变为它的相反数。
- 在遍历过程中,当元素映射到的位置的元素为负数,说明这个位置重复出现。
- 最后遍历数组,发现某个位置的元素大于 0,说明这个位置表示丢失的那个数。
- 这种方法会修改原数组,不过我们最后可以将数组还原。
- 时间复杂度为
O(n)。 - 空间复杂度为
O(1)。
1 | public class LeetCode_00645 { |
- 运用位运算。
- 将
1~n所有数与数组中的所有数进行异或,得到的结果是重复的数与丢失的数的异或值,记为t。 - 根据这个异或值
t得到它最后一个 1 代表的数,根据这个数来进行分组。可以把数分为两组,一组对应二进制位为 0,进行&运算之后为 0;另一组对应二进制位为 1,进行&运算之后不为 0。 - 将
1~n所有数与数组中的所有数按照上述分组方式进行异或,得到的两个值就代表重复的数和丢失的数。 - 最后遍历原数组确定哪个是重复的数即可,另一个就是丢失的数。
- 时间复杂度为
O(n)。 - 空间复杂度为
O(1)。
1 | public class LeetCode_00645 { |