leetcode 260,136,137 数字只出现一次

数字只出现一次

代码:

 public static void main(String[] args) {
//        int[] arr = {2, 2, 1};
//        int num = singleNumber(arr);
//        System.out.println(num);

//        int[] arr={2,1,2,3,4,1};
//        int[] nums = singleNumber2(arr);
//        System.out.println(Arrays.toString(nums));

//        int[] arr={2,2,3,2};
        int[] arr={0,1,0,1,0,1,99};
        int num = singleNumber3(arr);
        System.out.println(num);

    }

    /**
     * 只出现一次的数字  其余数字都出现两次,只有一个数字出现一次
     * 达到只使用线性的时间复杂度  不使用额外的空间
     * 使用异或运算 相同的元素进行异或运算 为0  0与任何元素异或都是元素本身
     *
     * @Date: 2020/6/9 23:15
     * @Author: fuGuoWen
     * @Return int 返回出现一次的数字
     * @Throws 无
     */
    public static int singleNumber(int[] nums) {
        int result = 0;
        for (int i = 0; i < nums.length; i++) {
            result ^= nums[i];
        }
        return result;
    }


    /**
     * 恰好有两个元素出现一次,其余的元素都是出现两次
     * 解决方案:
     * 1.对所有的元素做异或操作
     * 2.对异或以后的结果取低位第一个为1 的值 temp
     * 3.对整个元素继续进行遍历,如果当前元素的值与temp 最高位的值相同 返回的值不为0,
     * 如果当前元素的值与temp 最高位的值不同,返回的是0
     *
     * 算法 具备 线性的时间复杂度 和常量的空间复杂度
     *
     * @Date: 2020/6/9 23:28
     * @Author: fuGuoWen
     * @Return int[] 整形数组
     * @Throws 无
     */
    public static int[] singleNumber2(int[] nums) {
        int result=0;
        /** 第一步: 所有的元素进行异或,会得到唯一的两个元素的异或值 */
        for(int i=0;i<nums.length;i++){
            result^=nums[i];
        }
        /** 第二步 获得result低位的第一个不为0 的值 */
        int temp = 1;
        while (result != 0) {
            if ((result & 1) == 1) {
                break;
            }
            temp <<= 1;
            result >>= 1;
        }

        int[] arr=new int[2];
        for(int i=0;i<nums.length;i++){
            if((nums[i]&temp)==0){
                /**
                 * 第三步  对所有的元素进行与最高位的元素的值进行与运算  与最高位元素相同的值 进行的计算不为0
                 * 与最高位元素相同的值 进行的计算结果为0
                 * */
                arr[0]^=nums[i];
            }else{
                arr[1]^=nums[i];
            }
        }
        return arr;
    }

    /**
     * 只有一个元素出现了一次,其他的元素都是出现了三次
     * 解决思路
     * 1.
     * @Date: 2020/6/10 0:26
     * @Author: fuguowen
     * @Return
     * @Throws
     */
    public static int singleNumber3(int[] nums) {
        /** 第一步  遍历数组的每一位按照二进制位进行累加 */
        int[] bits = new int[32];
        for (int i = 0; i < 32; i++) {
            for (int j = 0; j < nums.length; j++) {
                bits[i] += (nums[j] & 1);
                nums[j] >>= 1;
            }
        }
        /**
         * 第二步 高位元素存储在下标比较大的位置
         * 从高位元素进行遍历,先进行右移,再进行跟3取模,求余,最后获得元素就是只出现一次的元素
         * */
        int result = 0;
        for (int i = 31; i >= 0; i--) {
            result <<= 1;
            result += (bits[i] % 3);
        }
        return result;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章