「力扣算法合集」

位运算前五题概述:

1.打印所给数字的二进制形式

2.二的幂

3.四的幂

4.比特位计数

5.丢失的数字


0、三目运算符

三目运算符表达式:A ? B : C
可以这么理解
if(A == true){
return B;
}
if(A == false){
return C;
}

一、打印所给数字的二进制形式(整形数字)

Notes:
我自己加了一个题,感觉这个很基础,所以拿出来给大家。

0.运行结果

在这里插入图片描述

1.题目如下

随机给你一个整形数字,请你打印该数字的所有二进制位

示例1
n == 8
8的所有二进制位:00000000000000000000000000001000

示例2
n == 7
7的所有二进制位:00000000000000000000000000000111

2.代码如下

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		printB(5);
		printB(4);
		printB(Integer.MIN_VALUE);
		printB(Integer.MAX_VALUE);
	}
	public static void printB(int a)
	{
		for(int i = 31; i >= 0; i--)
		{
			System.out.print(((1 << i) & a) == 0 ? 0 : 1);
		}
		System.out.println();
	}

3.代码解析

	public static void printB(int a)
	{
		for(int i = 31; i >= 0; i--)
		{
			//int类型的数据是32位,位置下标是0~31
			System.out.print(((1 << i) & a) == 0 ? 0 : 1);
			//每次将1向左移动i位,如果数字a的第i个位置为0,
			//则((1 << i) & a) == 0成立,代表该位置为0,
			//若是((1 << i) & a) == 0不成了,代表该位置为1.
			
			//实例讲解
			//4 
			//二进制表达式为00000000000000000000000000000100
			//1 & 0 = 0, 0代表false
			//1 & 1 = 1, 1代表true
			//下面开始模拟
        //0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
   //下标:31  ...........                                       4 3 2 1 0 	
			//1 << 31  & 0 == 0
			//.......
			//1 << 2   & 1 == 1
			//1 << 1   & 0 == 0
			//1 << 0   & 0 == 0
		}	
		System.out.println();
	}

二、2的幂(力扣231题)

0.运行结果

在这里插入图片描述

1.题目如下

给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。

如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。

示例 1:
输入:n = 1
输出:true
解释:20 = 1

示例 2:
输入:n = 16
输出:true
解释:24 = 16

示例 3:
输入:n = 3
输出:false

示例 4:
输入:n = 4
输出:true

示例 5:
输入:n = 5
输出:false

提示:
-2^31 <= n <= 2^31 - 1

2.代码如下

	public boolean isPowerOfTwo(int n) {
        if(n == 0) return false;
        if(n < 0) return false;
        return (n&(n-1)) == 0;
    }

3.代码解析

	public boolean isPowerOfTwo(int n) {
        //边界条件,如果所给数字为0,或者所给数字小于0,都是false,因为2的幂为大于0
        if(n == 0) return false;
        if(n < 0) return false;
        //如果不是0,或者负数
        //进行判断,判断表达式为(n&(n-1)) == 0
        return (n&(n-1)) == 0;
        //实例解析
        //n == 4
        //4的二进制为 00000100
        //n - 1 == 3
        //0的二进制为 00000011
        //4 & 3 == 0
		
		//总结:
		//2的幂的二进制表达式其实就是某一位为1,其余都是0
		//2的幂 - 1 的二进制其实就是2的幂为1的位置往后全是1
		//举例:
		//8的二进制表达式:00000000000000000000000000001000
		//7的二进制表达式:00000000000000000000000000000111
    }

大家可以用第一题的代码进行测试


三、4的幂(力扣342题)

0.运行结果

在这里插入图片描述

1.题目如下

给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true ;否则,返回 false 。

整数 n 是 4 的幂次方需满足:存在整数 x 使得 n == 4x

示例 1:
输入:n = 16
输出:true

示例 2:
输入:n = 5
输出:false

示例 3:
输入:n = 1
输出:true

提示:

-2^31 <= n <= 2^31 - 1

2.代码如下

    public boolean isPowerOfFour(int n) {
        if(n<=0)return false;
        while(n % 4 == 0)n/= 4;
        return n == 1;
    }

3.代码解析

    public boolean isPowerOfFour(int n) {
    	//边界条件
        if(n<=0)return false;
        //如果所给数字n除以4不为0,进行循环
        while(n % 4 == 0)
        	n/= 4;
        //最后进行判断n==1,如果n==1成立,说明所给数字是4的幂,如果n==1不成立,说明所给数字不是4的幂
        return n == 1;
        //实例解析1
        //n == 8
        //while(n % 4 == 0)	n/= 4;
        //8 % 4 == 0 因为8/4 == 2,余数为0,所以8 % 4 == 0成立,进行8/4 = 2,所以n == 2, 2 % 4 == 2,余数为2,因为2/4不能整除,商为0。结束循环。
        //最后进行判断n == 1, n为2,所以表达式n == 1 不成立,返回false。
        
        //实例解析2
        //n == 16
        //while(n % 4 == 0)	n/= 4;
        //16 % 4 == 0 因为16/4 == 4,余数为0,所以16 % 4 == 0成立,
        //进行16/4 = 4,所以n == 4, 4 % 4 == 0,余数为0,所以4 % 4 == 0成立
        //进行4 /4 = 1,所以n == 1, 1 % 4 == 1, 余数为1,所以1 % 4 == 0 不成立,结束循环 
        //最后进行判断n == 1, n为1,所以表达式n == 1 成立,返回true。
    }

四、比特位计数(力扣338题)

0.运行结果

在这里插入图片描述

1.题目如下

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

示例 1:
输入:n = 2
输出:[0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10

示例 2:
输入:n = 5
输出:[0,1,1,2,1,2]
解释:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
提示:
0 <= n <= 10^5

2.代码如下

	public int[] countBits(int num) {
		int[] ans = new int[num + 1];
		for (int i = 1; i <= num; i++) {
			ans[i] = ans[i >> 1] + (i & 1);
		}
		return ans;
	}

3.代码解析

	//采用一个数组进行计数,名称为bit数组
	//对于正整数n,将n的二进制表示右移一位,等价于将其二进制表示的最低位去掉,得到的数是n/2
	//如果bit[n/2]的值已经知道,那么从bit[n/2]的值推算出bit[n]的值
	//由此,可以将正整数n分为两类,一是奇数,二是偶数
	//有如下公式,
	//1 所给数字n为奇数,bit[n] = bit[n/2] + 1
	//2 所给数字n为偶数,bit[n] = bit[n/2]
	//综上所述,我们可以将公式1和公式2综合在一起,最后的表达式为bit[n/2] + n % 2。
	public int[] countBits(int num) {
		int[] ans = new int[num + 1];
		for (int i = 1; i <= num; i++) {
			ans[i] = ans[i >> 1] + (i & 1);
		}
		return ans;
	}
	//我们以示例2进行解析
	//根据示例我们可以得出,所需要求的比特位长度为n+1,因为二进制是从下标0开始算起
	//示例 2:
	//输入:n = 5
	//输出:[0,1,1,2,1,2]
	//解释:
	//0 --> 0
	//1 --> 1
	//2 --> 10
	//3 --> 11
	//4 --> 100
	//5 --> 101
	//首先申请一个长度为n+1的bit数组
	//进行for循环
	//i == 0 ,ans[0] = 0;
	//i == 1 时,ans[1] = ans[0] + (1 & 1) == 0 + 1 = 1;
	//i == 2 时,ans[2] = ans[1] + (2 & 1) == 1 + 0 = 1;
	//i == 3 时,ans[3] = ans[1] + (3 & 1) == 1 + 1 = 2;
	//i == 4 时,ans[4] = ans[2] + (4 & 1) == 1 + 0 = 1;
	//i == 5 时,ans[5] = ans[2] + (5 & 1) == 1 + 1 = 2;
	//返回bit数组,bit数组为[0, 1, 1, 2, 1, 2]。

五、丢失的数字(力扣268题)

0.运行结果

在这里插入图片描述

1.题目如下

给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

示例 1:
输入:nums = [3,0,1]
输出:2
解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,因为它没有出现在 nums 中。

示例 2:
输入:nums = [0,1]
输出:2
解释:n = 2,因为有 2 个数字,所以所有的数字都在范围 [0,2] 内。2 是丢失的数字,因为它没有出现在 nums 中。

示例 3:
输入:nums = [9,6,4,2,3,5,7,0,1]
输出:8
解释:n = 9,因为有 9 个数字,所以所有的数字都在范围 [0,9] 内。8 是丢失的数字,因为它没有出现在 nums 中。

示例 4:
输入:nums = [0]
输出:1
解释:n = 1,因为有 1 个数字,所以所有的数字都在范围 [0,1] 内。1 是丢失的数字,因为它没有出现在 nums 中。

提示:
n == nums.length
1 <= n <= 10^4
0 <= nums[i] <= n
nums 中的所有数字都 独一无二

2.代码如下

	public int missingNumber(int[] nums) {
        int n = nums.length;
        int res = 0;
        res ^= n;
        for (int i = 0; i < n; i++)
            res ^= i ^ nums[i];
        return res;
    }

3.代码解析

	public int missingNumber(int[] nums) {
        int n = nums.length;
        int res = 0;
        res ^= n;//此处也可以写成res = n。
        for (int i = 0; i < n; i++)//这个for循环的作用其实就是将0~n的数字进行异或,因为相同的数字异或为0
            res ^= i ^ nums[i];
		//实例解析
		//我们以示例3为例
		//示例 3:
		//输入:nums = [9,6,4,2,3,5,7,0,1]
		//输出:8
		
		//n = 9,也就是说是[0~9]范围的数字,看看缺少哪个
		//res = 9;进行for循环
		//i == 0 , res ^= i ^ nums[i]; res = 9 ^(0 ^ 9) == 0;
		//i == 1 , res ^= i ^ nums[i]; res = 0 ^(1 ^ 6) == 7;
		//i == 2 , res ^= i ^ nums[i]; res = 7 ^(2 ^ 4) == 1;
		//i == 3 , res ^= i ^ nums[i]; res = 9 ^(3 ^ 2) == 0;
		//i == 4 , res ^= i ^ nums[i]; res = 9 ^(4 ^ 3) == 7;
		//i == 5 , res ^= i ^ nums[i]; res = 9 ^(5 ^ 5) == 7;
		//i == 6 , res ^= i ^ nums[i]; res = 9 ^(6 ^ 7) == 6;
		//i == 7 , res ^= i ^ nums[i]; res = 9 ^(7 ^ 0) == 1;
		//i == 8 , res ^= i ^ nums[i]; res = 9 ^(8 ^ 1) == 8;
        return res;
    }

总结:

接下来还会进行与位运算相关的题目解析,欢迎大家指导!


  • 34
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 27
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董陌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值