• 260. Single Number III


    260. Single Number III

    Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

    For example:

    Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

    Note:

    1. The order of the result is not important. So in the above example, [5, 3] is also correct.
    2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

    上两个的升级版,但是跟上两个思路又完全不同。真是。。。

    两种做法,一个位运算肯定是技巧性很高的,一个是set维护。

    Java set做法:

      遍历这个数组,第一次出现的添加进去,只要出现了第二次,则remove,剩下的就是单个了的数集合了,也适用用于找出数组中成对出现数中的所有单个数。最后把这个set集合元素添到数组就行了。

      查了资料,貌似不能直接把一个set集合转换成Array,toArray也只能装换成object,参考可见:https://ask.helplib.com/106360

    public class Solution {
        public int[] singleNumber(int[] nums) {
            Set<Integer> set = new HashSet<Integer>();
            for(int n : nums) {
                if(!set.contains(n)) {
                    set.add(n);
                }else {
                    set.remove(n);
                }
            }
            
            int[] ans = new int[set.size()];
            int cnt = 0;
            
            for(int n:set) {
                ans[cnt++] = n;
            }
            return ans;
        }
    }

    位运算做法:

     这个需要很强的计算机底层二进制思想,看到这个题目后,看到这个数字大脑里就想到的是这个数字背后的二进制。

    1.不管以哪个数开始 ^ 两个相同的数,都会抵消。

    2.diff &= -diff; 或者 diff = diff & (~(diff - 1));求出从右开始第一位不相同的位数,用来区分出数组中两个不同的数。保留该位并将其他位置为 0 再进行与运算,结果一个肯定为0,另一个与运算肯定不为0,再进行下面的(3。

    3.ans[] = {0},0和任意一个数^亦或得它本身,区分后靠这个直接赋值给ans。

    一开始傻逼了,就因为这个3有点唬住了,其实也可以直接取。当然也可保留其他diff的数值为1的位,因为1位都是两个数当前位不同亦或的结果,但是为了简单只保存一个即可。

    public class Solution {
        public static int[] singleNumber(int[] nums) {
             
                    int[] ans = new int[2];
                    int diff = 0;
                    for(int num : nums) {
                        diff ^= num;
                    }
                    diff &= -diff;
                    for(int num : nums) {
                        if((num & diff) == 0) {
                            ans[0] ^= num;
                        }else {
                            ans[1] ^= num;
                        }
                    }
                    return ans;
                }
    }
  • 相关阅读:
    Yii2设计模式——工厂方法模式
    Yii2设计模式——静态工厂模式
    Yii2设计模式——简单工厂模式
    Yii2设计模式——注册树模式
    Yii2设计模式——单例模式
    nginx负载均衡指令least_conn的真正含义
    Yii2设计模式——Yii2中用到哪些设计模式?
    Yii2设计模式——设计模式简介
    Openresty的同步输出与流式响应
    Scope 功能的改进
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/7282441.html
Copyright © 2020-2023  润新知