小浩算法-java题解(位运算篇)


原文链接
https://www.geekxh.com/0.0.%E5%AD%A6%E4%B9%A0%E9%A1%BB%E7%9F%A5/01.html
这里是把这个大佬的题解用java写一下做个记录

位运算篇

连续n个数的和

求 1 2 … n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
示例 1:

输入: n = 3 输出: 6

解题思路: 递归,A&&B,A为true,那么返回B的布尔值,A为false,那么返回false,所以我们把递归的返回条件设置成A,递归的主体就是B
也就是:

class Solution {
    public int sumNums(int n) {
        boolean b = n > 0 && ((n + = sumNums(n - 1)) > 0);
        return n;
    }
}

第231题:2的幂

给定一个整数,编写一个函数来判断它是否是 2 的幂次方。
示例 1:

输入: 1
输出: true
解释: 20 = 1

解题思路:
方法一:判断n%2为0时,n/=2的结果是不是1。

class Solution {
    public boolean isPowerOfTwo(int n) {
    if (n == 0) return false;
    while (n % 2 == 0) n /= 2;
    return n == 1;
    }
}

方法二: 对于N为2的幂的数,都有 N&(N-1)=0。

class Solution {
    public boolean isPowerOfTwo(int n) {
       return n >0 &&  (n&(n-1))==0;
    }
}

第191题:位1的个数

编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
示例 1:

输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

解题思路:
方法一:利用掩码来计算,碰到掩码mask&n!=0说明这位是1,计数。最后返回结果。

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
         int result = 0;
        //初始化掩码为1
        int mask = 1;
        for (int i = 0; i < 32; i++) {
            if ((n & mask) != 0) {
                result++;
            }
            mask = mask << 1;
        }
        return result;
    }
}

方法二: 根据上一题的思路,n&n(n-1)进行位运算,那么最低位的1会变成0。我们计数又多少次这样成立就ok。

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int count = 0;
        while(n != 0)
        {
            n =(n & (n - 1)) ;
            count++;
        }
        return count;
    }
}

第136题:只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

解题思路:用异或,自己和自己异或是0,剩下的就是结果

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

第137题:只出现一次的数字Ⅱ

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。说明:你的算法应该具有线性时间复杂度。你可以不使用额外空间来实现吗?
说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,3,2]
输出: 3

解题思路:
方法一:哈希表,存储元素和次数,然后再遍历找到那个次数为1的。

class Solution {
    public int singleNumber(int[] nums) {
             HashMap<Integer,Integer> map=new HashMap<Integer,Integer>();
             for(int num:nums)
             {
                 map.put(num,map.getOrDefault(num,0)+1);

             }
             for(int k:map.keySet())
              if(map.get(k)==1) return k;
             return -1;
    }
}

方法二: 数学,[A,A,A,B,B,B,C,C,C] 和 [A,A,A,B,B,B,C],差了两个C。即:

3×(a b c)−(a a a b b b c)=2c,也就是去重后数组的和x3-现在数组的和是c的两倍。

class Solution {
    public int singleNumber(int[] nums) {
            Set<Long> set=new HashSet<>();
            long sumSet=0,sumArr=0;
            for(int num:nums)
            {
                sumArr+=num;
                set.add((long)num);
            }
            for(long s:set) sumSet+=s;
            return (int)((sumSet*3-sumArr)/2);
    }
}

方法三:位运算。
。。。。。。。。。。。。。

第268题:缺失数字

给定一个包含 0, 1, 2, …, n 中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。

示例 1:

输入: [3,0,1]
输出: 2

解题思路:
方法一:1到n的和是(n+1)n/2,我们算出总的和,然后减去这个数组的和,剩下的就是我们要求的。因为有一个0,所以数组的长度也就是1到n的长度。
3 0 1 作为例子,n
(n+1)/2的结果是6,然后数组的结果是4,所以差2。

class Solution {
    public int missingNumber(int[] nums) {
          int len=nums.length;
          int sum=(len+1)*len/2;
          int tsum=0;
          for(int num:nums)
            tsum+=num;
          return sum-tsum;     
    }
}

方法二:异或,假设是n然后用 ans^ =nums[i]^ i来找到那个值。
3 0 1作为例子 3^ (3 ^ 0) ^ (0 ^1) ^ (1 ^ 2),结果就是2,括号里是nums[i] ^ i。

class Solution {
    public int missingNumber(int[] nums) {

        int ans=nums.length;
        for(int i=0;i<nums.length;i++)
           ans^=nums[i]^i;
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值