首页 > 试题广场 >

数组中只出现一次的两个数字

[编程题]数组中只出现一次的两个数字
  • 热度指数:119623 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

数据范围:数组长度 ,数组中每个数的大小
要求:空间复杂度 ,时间复杂度

提示:输出时按非降序排列。
示例1

输入

[1,4,1,6]

输出

[4,6]

说明

返回的结果中较小的数排在前面     
示例2

输入

[1,2,3,3,2,9]

输出

[1,9]
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] nums) {
        // write code here
        int[] result = new int[2];
        HashMap<Integer, Integer> map = new LinkedHashMap<>();
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(nums[i])) {
                map.put(nums[i], map.get(nums[i]) + 1);
            } else {
                map.put(nums[i], 1);
            }
        }
        int k = 0;
        for (int i = 0; i < nums.length; i++) {
            if (map.get(nums[i]) == 1) {
                result[k] = nums[i];
                k++;
            }
        }
        // for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
        //     if (entry.getValue() == 1){
        //         result[k] = entry.getKey();
        //         k++;
        //     }
        //     if (k == 2){
        //         break;
        //     }
        // }
        Arrays.sort(result);
        return result;
    }
}
发表于 2024-09-17 12:05:56 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] nums) {
        // write code here

        // 核心思想:采用异或运算的方法,先求出这两个数字的异或值,再根据最低为1的位分别求出两个数值
        // 算法时间复杂度O(N),额外空间复杂度O(1)

        // 1.先异或一轮,得到一个异或值,表示两个只出现了一次的数字的异或结果
        int n = nums.length;
        int xor = 0;
        for (int i = 0; i < n; i++) {
            xor ^= nums[i];
        }

        // 2.在此基础上,通过位运算得到一个01组成的二进制数,这个数只有一个1,其余位置均为0,且1的那个位置是异或结果的1的最低位
        xor = xor & (~xor + 1);

        // 此时,xor只有一位是1,意义是:两个只出现一次数字在这个位置上数字不同
        // 3.再遍历一轮nums数组,此时根据与xor的与结果分成两组,每一组分别异或出一个值,即为待求值
        int xor1 = 0;
        int xor2 = 0;
        for (int i = 0; i < n; i++) {
            if ((nums[i] & xor) == 0) {
                xor1 ^= nums[i];
            } else {
                xor2 ^= nums[i];
            }
        }

        // 4.按照题意输出结果
        int[] result = new int[2];
        result[0] = Math.min(xor1, xor2);
        result[1] = Math.max(xor1, xor2);
        return result;
    }
}

发表于 2024-09-11 11:18:53 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] nums) {
        // write code here
        HashSet<Integer> set = new HashSet<>();
        for (int num : nums) {
            if (set.contains(num)) {
                set.remove(num);
            } else {
                set.add(num);
            }
        }
        return set.stream().sorted().mapToInt(Integer::intValue).toArray();
    }
}

发表于 2024-05-07 11:41:56 回复(0)
public int[] FindNumsAppearOnce (int[] nums) {
    // write code here
    int[] res = new int[2];
    if (nums == null || nums.length == 0) return res;

    Map<Integer, Integer> map = new HashMap<>();

    for(int i=0;i<nums.length;i++) {
        int key = nums[i];
        if(map.containsKey(key)) {
            map.put(key, map.get(key)+1);
        } else {
            map.put(key, 1);
        }
    }
    Set<Map.Entry<Integer, Integer>> et = map.entrySet();
    int idx = 0;
    for(Map.Entry<Integer, Integer> item : et) {
        if(item.getValue().equals(1)) {
            res[idx++] = item.getKey();
        }
        if (idx >= 2) break; 
    }
    
    return res;
}

发表于 2024-04-15 23:36:21 回复(0)
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] nums) {
         Arrays.sort(nums);
        if(nums.length==2){
            return  nums;
        }
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();

       
        //哈希表记录数组中出现的每个数字
        for (int i = 0; i < nums.length; i++){
            map.put(nums[i],0);
        }

        for (int i = 0; i < nums.length; i++){
            map.put(nums[i],map.get(nums[i])+1);
        }
        int[] result = new int[2];
        int count = 0;
        for (int i = 0; i < nums.length; i++){
           if(map.get(nums[i])==1){
             result[count++] = nums[i];
           }
        }
               
   
       return result;
    }
}
编辑于 2024-03-26 17:02:49 回复(0)
public int[] FindNumsAppearOnce (int[] nums) {
    // write code here
    int[] res=new int[2];
    int index=0;
    HashMap<Integer ,Integer> map = new HashMap<>();
    for(int num:nums){
        map.put(num ,map.getOrDefault(num ,0)+1);
    }
    Iterator<Map.Entry<Integer ,Integer>> iter=map.entrySet().iterator();
    while(iter.hasNext()){
        Map.Entry<Integer ,Integer> entry=iter.next();
        if(entry.getValue()==1){
            res[index++]=entry.getKey();
        }
    }
    return res;
}

发表于 2024-03-24 14:26:37 回复(0)
public int[] FindNumsAppearOnce (int[] nums) {
        // write code here
        int[] ret = new int[2];
        if (nums.length == 0) {
            return null;
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(nums[i])) {
                map.remove(nums[i]);
                continue;
            }
            map.put(nums[i], 1);
        }
        int i = 0;
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            ret[i++] = entry.getKey();
        }
        return ret;
    }

编辑于 2024-02-02 10:27:02 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] nums) {
        // write code here
        Map<Integer, Integer> hash = new HashMap<>();
        int x[]=new int[2];
        for (int i = 0; i < nums.length; i++) {
            if (hash.containsKey(nums[i])) {     //查找相同值
            hash.remove(nums[i]);//删除已经发现的重复的值
            } else hash.put(nums[i], 1);//不想同在map中添加
        }//循环结束map中一定只有两个元素
            int j=0;
        for(int i=0;i<nums.length;i++){//再进行一次循环 找出这两个值
            if(hash.containsKey(nums[i])){
                x[j++]=nums[i];
            }
        }
        if(x[0]>x[1]){//判断大小进行排序
           x[0]=x[1]+x[0];
           x[1]=x[0]-x[1];
           x[0]=x[0]-x[1];
        }
        return x;
    }
}
发表于 2023-11-17 16:36:38 回复(0)
  Map<Integer, Integer> maps = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            if (maps.containsKey(nums[i])) {
                Integer a = maps.get(nums[i]);
                maps.put(nums[i], ++a);
            } else {
                maps.put(nums[i], 1);
            }
        }
        List<Integer> a = new ArrayList();
        maps.forEach((k, v)-> {if (k == 1) {
        a.add(v);
        }
                              });
       int b[]= Arrays.stream(a.stream().toArray(Integer[] ::new)).mapToInt(Integer::valueOf).toArray(); 
       Arrays.sort(b);       
       return b;            

发表于 2023-11-07 10:28:42 回复(0)
思路:使用异或^思想,首先任意非0数异或0都是它本身,即a^0 = a (a > 0),任意相同数异或自己本身都是0,即 a^a = 0;
1,定义一个num变量,初始值为0,用来保存异或后的结果
2,将nums数组中的元素换种表达方式,tmp = 1 << nums[i],将数字1左移nums[i]位
3,循环遍历nums中的tmp,并且是num ^= tmp
4,遍历完后将num转为二进制字符串,字符串中每个1后面的字符个数就是nums中只出现一次的元素的值.


以示例1来说,将数组的值换一种表现方式
1 ---->10
4 ----->10000
6 ------>1000000
数组就变成了【10,10000,10,1000000】
遍历数组所做的运算就是
0^10^10000^10^1000000 = 1010000

所以num的最终结果就是1010000,第一个1后面有6个字符所以6就是nums中出现一次的值,第二个1后面有4个字符,所以4也是nums中出现一次的值,所以最终结果是[4,6]

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] nums) {
        // write code here
        int num = 0;
        for(int a:nums){
            //将nums[i]转换为将数字1左移nums[i]位后的结果
            int b = 1 << a;
            //将转换后的结果和num进行异或
            num = num ^ b;
        }
        //将最终num的结果转为二进制字符串,字符串中每一个1都代表着只出现一次的数字
        String str = Integer.toBinaryString(num);
        //计算每个1后面的字符个数,就是最终的结果
        int a = str.length() - str.indexOf("1") - 1;
        int b = str.length() - str.lastIndexOf("1") - 1;

        return new int[]{b,a};
    }
}
发表于 2023-11-02 15:40:26 回复(1)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] nums) {
        // 1. 参数校验
        if(nums == null || nums.length == 0) {
            return null;
        }

        // 2. 创建哈希表存储元素以及对应的出现次数
        HashMap<Integer,Integer> map = new HashMap<>();

        // 3. 遍历数组元素,存储元素以及出现次数
        for(int i = 0;i < nums.length;i++) {
            // 4. 如果哈希表中不存在此元素,那就添加此元素
            if(!map.containsKey(nums[i])) {
                map.put(nums[i],1);
            } else {
                // 5. 如果哈希表中存在此元素,那就让他的 value + 1
                map.put(nums[i],map.get(nums[i]) + 1);
            }
        }

        // 6. 创建答案数组,保存数组中只出现一次的两个数字
        int[] ans = new int[2];
        int count = 0;

        // 7. 再次遍历数组,找到频率为 1 的两个数
        for(int i = 0;i < nums.length;i++) {
            if(map.get(nums[i]) == 1) {
                ans[count++] = nums[i];
            }
        }
        
        // 8. 题目要求升序
        if(ans[0] > ans[1]) {
            int tmp = ans[0];
            ans[0] = ans[1];
            ans[1] = tmp;
        }

        return ans;
    }
}

发表于 2023-09-09 08:57:40 回复(0)
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] nums) {
        // write code here
        Map<Integer, Integer> m = new HashMap<Integer, Integer>();
        //转成数组进行遍历获取到每个字符
        for (int index = 0; index < nums.length; index++) {
            //将获取到的值作为键
            //计数作为值
            int c = nums[index];
            //判断集合中是否存在键
            if (m.containsKey(c)) {
                //如果存在,那么在值的后面加1
                m.put(c, m.get(c) + 1);
                //如果不存在那么就创建一个键值用于记录
            } else {
                m.put(c, 1);
            }
        }
        Set<Integer> s1 = m.keySet();
        int num []= new int[2];
        int count = 0;
        for (int key : s1) {
            //通过集合遍历得到值
            int value = m.get(key);
            if (value == 1) {
                num[count] = key;
                count ++;
            }
            if(count==2)
            {break;}

        }
        return num;
    }
}
发表于 2023-07-06 19:47:59 回复(0)
public int[] FindNumsAppearOnce (int[] array) {
        // write code here
        Map<Integer, Integer> map = new LinkedHashMap<>();
        for (int arr : array) {
            if (map.containsKey(arr)) {
                map.remove(arr);
            } else {
                map.put(arr, arr);
            }
        }
        int[] ints = map.entrySet().stream().mapToInt(e -> e.getKey()).sorted().toArray();
        return  ints;
    }

发表于 2023-06-15 09:50:13 回复(0)
搞不懂,怎么还要sort一边
public int[] FindNumsAppearOnce (int[] array) {
// write code here
int[] map = new int[1000001];
int[] res = new int[2];
for(int num : array) {
map[num]++;
}
int index = 0;
for(int num : array) {
if(map[num] == 1) {
res[index++] = num;
}
}
Arrays.sort(res);
return res;

}

发表于 2023-04-22 14:17:54 回复(1)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] array) {
        int ans=0;
        for(int i=0;i<array.length;i++){
            ans=ans^array[i];
        }
        int h=1;
        while((h&ans)==0){
            h<<=1;
        }
        int group1=0;
        int group2=0;
        for(int i=0;i<array.length;i++){
            if((h&array[i])==0){
                group1=group1^array[i];
            }else{
                group2=group2^array[i];
            }
        }
        
        return new int[]{Math.min(group1,group2),Math.max(group1,group2)};

    }
}

发表于 2023-04-21 22:11:36 回复(1)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] array) {
        // write code here
        if(array == null || array.length <= 0) {
            return null;
        }
        Set<Integer> set = new TreeSet<>();
        for(int a : array) {
            if (set.contains(a)) {
                set.remove(a);
            }else {
                set.add(a);
            }
        }
        //最后剩下的元素就是只出现一次的数字
        int[] result = new int[2];
        Iterator<Integer> it = set.iterator();
        int index = 0;
        while(it.hasNext()) {
            result[index++] = it.next();
        }
        return result;
    }
}

发表于 2023-04-13 07:42:33 回复(0)
public class Solution {
    public int[] FindNumsAppearOnce (int[] array) {
        Map<Integer, Integer> map = new HashMap();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < array.length; i++) {
            if (map.containsKey(array[i])) {
                map.put(array[i], map.get(array[i]) + 1);
            } else {
                map.put(array[i], 1);
            }
        }
        Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
        for (Map.Entry<Integer, Integer> entry : entries) {
            if (entry.getValue() == 1) {
                list.add(entry.getKey());
            }
        }
        Collections.sort(list);
        return list.stream().mapToInt(Integer::intValue).toArray();
    }
}

发表于 2023-03-18 23:01:27 回复(0)
 /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出  现       一次的数字。
     *
     * @param array int整型一维数组
     * @return int整型一维数组
     */
    public static int[] FindNumsAppearOnce(int[] array) {
        // 1 创建一个hashMap key:数组元素 value:统计数组元素出现次数
        Map<Integer, Integer> map = new HashMap<>();
        ArrayList<Integer> res = new ArrayList<>();
        for (int i = 0; i < array.length; i++) {
            if (map.containsKey(array[i])) {
                map.put(array[i],array[i]+1);
            }else {
                map.put(array[i],1);
            }
        }
        for (Map.Entry<Integer,Integer> entry : map.entrySet()) {
            if (entry.getValue().equals(1)) {
                res.add(entry.getKey());
            }
        }
        res.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // ASC
                return o1-o2;
            }
        });
        return res.stream().filter(ele -> ele != null).mapToInt(r -> r).toArray();
    }
发表于 2023-03-11 15:51:14 回复(0)
使用TreeMap, treeSet能很容易解决
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param array int整型一维数组
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] array) {
        // write code here
        TreeMap<Integer, Integer> map=new TreeMap<>();
        for(int a: array){
            int count=1;
            if(map.containsKey(a)){
                count=map.get(a)+1;
                map.put(a,count);
            }
            else{
                map.put(a,count);
            }
        }
        Set<Integer> set=new TreeSet<>();
        map.forEach((i,j)->{
            if(j==1){
                set.add(i);
            }
        });
        int[] ret=new int[set.size()];
        int x=0;
        for(Integer s: set){
            ret[x++]=(int)s;
        }
        return ret;
    }
}

发表于 2023-03-04 11:52:00 回复(0)
先排序,如果出现重复的数字,那么一定相邻
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] array) {
        // 排序
        heapSort(array);

        // 返回值
        int[] res = new int[2];
        // 返回值数组res 的索引,用于添加数据
        int resIndex = 0,
                y = 0; // 保存每次array的元素 异或结果

        // 遍历数组
        for (int i = 0; i < array.length - 1; i++) {
            // 首次y的结果是 array[i],如果后面的循环遇到相同的,将回到0的位置
            y  ^= array[i];
            // 如果当前元素 和 下一位元素不同,并且y不为0时,表示当前元素没有重复
            if(array[i+1] != y && y != 0){
                res[resIndex] = y; // 加入数组
                resIndex++; // 索引后移
                y = 0; // y置为0,下次继续异或
            }
        }
        // 最后判断如果1位置等于0,表示最后一个不重复的数字在 数组末尾,将末尾数赋值给res的1位置
        if(res[1] == 0) res[1] = array[array.length - 1];

        // 最终返回
        return res;
    }
    public void heapSort(int[] arr){
        for (int i = arr.length / 2 - 1; i >= 0; i--) buildBigHeap(arr, i, arr.length);

        int temp;
        for (int i = arr.length - 1; i > 0; i--) {
            temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;

            buildBigHeap(arr, 0, i);
        }
    }
    public void buildBigHeap(int[] arr, int i, int length){
        int temp = arr[i]; // 暂存当前节点的值

        for (int j = i * 2 + 1; j < length; j = j * 2 + 1) {
            // j为当前节点的左子节点, j+1是右子节点,如果右大于左,那么j指向右节点
            if((j + 1) < length && arr[j] < arr[j + 1]) j += 1;

            // 当前节点小于子节点
            if(temp < arr[j]){
                arr[i] = arr[j];
                i = j;
            }else{
                break;
            }
        }
        arr[i] = temp;
    }
}


发表于 2022-11-15 17:14:06 回复(0)

问题信息

上传者:牛客301499号
难度:
75条回答 6266浏览

热门推荐

通过挑战的用户

查看代码
数组中只出现一次的两个数字