JZ40-数组中只出现一次的数字

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

https://www.nowcoder.com/questionTerminal/389fc1c3d3be4479a154f63f495abff8?answerType=1&f=discussion

package algo.JZ.A3.JZ40;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class JZ40 {
    public static void main(String[] args) {
        int[] test = new int[]{2, 4, 3, 6, 3, 2, 5, 5};
        int[] num1 = new int[1];
        int[] num2 = new int[1];
//        new Solution().FindNumsAppearOnce(test, num1, num2);
        int[] ints = new Solution2().FindNumsAppearOnce(test);
        System.out.println(Arrays.toString(ints));
    }
}

class Solution {
    public void FindNumsAppearOnce(int[] array, int num1[], int num2[]) {
        if (array == null || array.length == 0) {
            return;
        }
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < array.length; i++) {
            if (!map.containsKey(array[i])) {
                map.put(array[i], 1);
            } else {
                map.put(array[i], 2);
            }
        }
        int count = 0;
        for (int i = 0; i < array.length; i++) {
            if (map.get(array[i]) == 1) {
                if (count == 0) {
                    num1[0] = array[i];
                    count++;
                } else {
                    num2[0] = array[i];
                }
            }
        }
    }
}

class Solution2 {
    public void swap(int[] a, int l, int r) {
        int o = a[l];
        a[l] = a[r];
        a[r] = o;
    }

    public int[] FindNumsAppearOnce(int[] array) {
        // write code here
        int[] a = new int[2];
        int x = array[0];
        //将数组中所有数字做异或处理
        //由于相同数字异或结果为0,0与数字x异或的结果为x
        //所以最终的结果为单独出现的数字的异或结果
        for (int i = 1; i < array.length; i++) {
            x ^= array[i];
        }
        int m = 1;
        //两个单独出现的数字若在m位相异,则在x中第m位为1
        while ((m & x) == 0) {
            m = m << 1;///求最后一个二进制位为 1 的数字的位置。1000 1;1000 10;1000 100;1000 1000。m左移4位
        }

//        int m = x & (-x);**********************这样可以直接计算出来m

        //根据第m位的值将原数组分为两组,单独出现的两个数字分在不同的组
        // (英文这两个数字在第m位异或结果为1,即1个为0,一个为1.a&m(1000,为1)==0,b&m==1)
        for (int i : array) {
            if ((m & i) == 0) {
                a[0] ^= i;
            } else {
                a[1] ^= i;
            }
        }
        if (a[0] > a[1]) {
            swap(a, 0, 1);
        }
        return a;
    }
}



全部评论

相关推荐

找工作勤劳小蜜蜂:自我描述部分太差,完全看不出想从事什么行业什么岗位,也看不出想在哪个地区发展,这样 会让HR很犹豫,从而把你简历否决掉。现在企业都很注重员工稳定性和专注性,特别对于热爱本行业的员工。 你实习的工作又太传统的it开发(老旧),这部分公司已经趋于被淘汰,新兴的互联网服务业,比如物流,电商,新传媒,游戏开发和传统的It开发有天然区别。不是说传统It开发不行,而是就业岗位太少,基本趋于饱和,很多老骨头还能坚持,不需要新血液。 工作区域(比如长三角,珠三角,成渝)等也是HR考虑的因素之一,也是要你有个坚定的决心。否则去几天,人跑了,HR会被用人单位骂死。
点赞 评论 收藏
分享
鱼专:别投了,我看到有人点了第二个链接投递,还没退出界面,不合适的邮件就发过来了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务