给你一个整数数组 nums
,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。
示例 1:
输入:nums = [1,2,1,3,2,5] 输出:[3,5] 解释:[5, 3] 也是有效的答案。
示例 2:
输入:nums = [-1,0] 输出:[-1,0]
示例 3:
输入:nums = [0,1] 输出:[1,0]
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/single-number-iii/description/?envType=daily-question&envId=2023-10-16
自己的思路
从小到大排序,先判断数组第一个和最后一个元素;然后判断中间元素、
元素判断条件是是否等于相邻的元素,首尾元素需要判断后一位或前一位元素,中间元素需要同时判断前一位和后一位的元素。
题目已经限制了结果数组的大小为2,可以直接定义结果数组。
代码
public class Solution{
public int[] singleNumber(int[] nums) {
public int[] singleNumber(int[] nums) {
Arrays.sort(nums);
int len = nums.length;
int j = 0;
int[] res = new int[2];
if (nums[0] != nums[1]) {
res[j++] = nums[0];
}
if (nums[len - 1] != nums[len - 2]) {
res[j++] = nums[len - 1];
}
for (int i = 0; i < len; i++) {
if (i != 0 && i != len - 1 && nums[i] != nums[i + 1] && nums[i] != nums[i - 1]){
res[j++] = nums[i];
}
}
return res;
}
}
结论
1、本来想使用虚拟数组,可惜存在负数,一时间不知道怎么处理负数。、
2、想使用HashSet(集合)去重性质,再做差得出重复元素,又想了一下,觉得好麻烦就算了。
力扣官方题解
1、哈希表
使用一个Map
来存储数组中每个数字的频率,然后通过迭代这个映射来找出频率为1的数字,并将它们添加到 ans
数组中
public class Solution {
public static int[] singleNumber(int[] nums) {
Map<Integer, Integer> freq = new HashMap<Integer, Integer>();
for (int num : nums) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
int[] ans = new int[2];
int index = 0;
for (Map.Entry<Integer, Integer> entry : freq.entrySet()) {
if (entry.getValue() == 1) {
ans[index++] = entry.getKey();
}
}
return ans;
}
public static void main(String[] args) {
int[] nums = {1,2,1,3,2,5};
// 1,1,2,2,3,5
for (int i : singleNumber(nums)) {
System.out.println(i);
}
}
}