其他分享
首页 > 其他分享> > LeetCode刷题(136,338,461)

LeetCode刷题(136,338,461)

作者:互联网

 解法一:利用哈希set存储

优点:由题意只有一个数字出现一次,容易想到hashset不能重复出现相同元素特性

缺点:耗时长,由于每次删除需要遍历hashset,并且使用了额外空间

public int singleNumber(int[] nums) {
       //由于题目中已经说明只有一个元素会出现一次,因此我们可以利用hashset的特性
        HashSet<Integer> hashSet=new HashSet();
        for (int num:nums){
            if (!hashSet.add(num)){//如果这个元素已经添加过了
                hashSet.remove(num);
            }else {
                hashSet.add(num);
            }
        }
        //添加完所有的元素,所有出现两次的元素已经被删除
        return hashSet.iterator().next();
    }

 

 解法二:位运算之异或

优点:没有使用额外空间,时间复杂度是O(n)

缺点:不容易想到

public int singleNumber(int[] nums) {
        int res=0;
       for (int num:nums){
           res=res^num;
       }
       return res;
    }

 

 

解法一:利用位运算中 n&(n-1)可以消去最后一位1的特性 

public int[] countBits(int n) {
        int[] res=new int[n+1];//因为是0~n,所以新数组的长度是n+1
        for (int i=1;i<n+1;i++){//数组的默认值是0,而0的二进制恰好是0个1
            res[i]=res[i&(i-1)]+1;//因为此操作可以消去最后一位1,我们逆向思维加上一个1
        }
        return res;
    }

 

 解法二:利用奇数的含1是他-1的偶然的含1量+1,偶数的含1量就是他除以2的含1量

                当然我们同样可以利用位运算来判断是奇数偶数

 

 public int[] countBits(int n) {
       //同样的,先new一个返回数组
        int[] res=new int[n+1];
        for (int i=1;i<n+1;i++){
            res[i]=(i&1)==1?res[i-1]+1:res[i>>1];
        }
        return res;
    }

 

利用异或运算,把不同的地方都变为1 ,在计算1的个数

public int hammingDistance(int x, int y) {
       //我们将两个数进行异或运算,那么不同的地方都将是一,我们只需要统计1的个数
        int num=0;
        for ( int i=x^y;i!=0;i=i&(i-1)){
            num++;
        }
        return num;
    }

 

 

标签:return,338,hashSet,int,res,461,num,136,public
来源: https://blog.csdn.net/qq_59539549/article/details/122819962