Java算法题分享(一)
在Java算法专栏,博主会分 1. 解题思路 2. 代码实现及解析 3. 总结 三部分整理算法解析,作为我们笔试手撕算法的资本,博主会慢慢整理出更多的不同的算法篇章,敬请期待!进去狠狠刷题~~
预祝大家笔试、面试轻松过,拿下满意offer~
文章目录
- 一、二进制中的1
- 1. 解题思路:
- 2. 代码实现及解析
- 3. 总结
- 二、判定素数
- 1. 解题思路
- 2. 代码实现及解析
- 3. 总结
- 三、最大公约数
- 1. 解题思路
- 2.代码实现及解析
- 3. 总结
- 四、Hanoi-problem
- 1.解题思路
- 2.代码实现
- 3.总结
一、二进制中的1
求一个整数在内存中储存时二进制位中所包含的1有多少个?
1. 解题思路:
- 我们可以找到二进制中的每一位1并一个一个删除,每删除一个就计数一次。
- 我们可以利用公式n&(n-1)来删除二进制中最右边的那一位1,然后计数一次。
- 解释: n - 1 会将 n 的二进制表示中最右边的为1的那一位变为 0 ,并且将这一位右边的所有位取反。然后 n & (n - 1) 会将 n 中最右边的 1 清除掉。例如, n = 6 (二进制为 110 ), n - 1 = 5 (二进制为 101 ), n & (n - 1) = 4 (二进制为 100 )。
2. 代码实现及解析
import java.util.Scanner;//求一个整数,在内存当中存储时,二进制1的个数。
public class Test {public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入:");int n=sc.nextInt();int ret=func(n);System.out.println(ret);sc.close();}public static int func(int n){int count=0;while(n!=0){n=n&(n-1);//循环消除掉n的二进制序列中所有的1,而后再赋值给n以便依次消除每一位1,//最后就n就变为了0count++; //计数}return count;}
}
3. 总结
利用公式 n&(n-1) 来消除二进制中最右边的1
关于位操作符还有很多应用,大家有兴趣可以去我的这篇文章末尾看一看JavaSE知识分享——运算符篇
二、判定素数
给出一个数n,判断是不是素数(只能被1和自身整除的数)
1. 解题思路
其实一般思路还是穷举,只是其实我们不用一直从2到n一直遍历下去,因为若当我们遍历到n的算术平方根时就已经够了。
2. 代码实现及解析
//给定一个数字,判定这个数字是否是素数
import java.util.Scanner;
import static java.lang.Math.*;public class PrimeNum {public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入您要判定的数:");int num= sc.nextInt();int ret=check(num);if(ret==0){System.out.println("不是素数!");}else{System.out.println("是素数!");}sc.close();}public static int check(int num){for (int i = 2; i <= sqrt(num); i++) { //遍历到sqrt(num),也就是num的算术平方根if(num%i==0){ //如果还能被其他数整除就返回0return 0;}}return 1;}
}
3. 总结
素数的判定遍历到n的算术平方根
三、最大公约数
给你两个整数,求它们的最大公约数
1. 解题思路
今天还是为大家分享经典的辗转相除法,更相减损法可以去了解下,但不推荐,效率低。
2.代码实现及解析
import java.util.Scanner;//给出两个整数求出他们的最大公因数
public class CommonDivisor {public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入:");int a = sc.nextInt();int b = sc.nextInt();int ret=fun(a,b);System.out.println(ret);}//辗转相除法public static int fun(int a,int b){//保证b为较大值if(a>b){int tmp=b;b=a;a=tmp;}int r=1;//重复用较大值除以较小值取余数,余数继续充当较小值,直到余数为0while(r!=0){r=b%a;b=a;a=r;}return b;}
}
3. 总结
辗转相除法求最大公约数
四、Hanoi-problem
汉诺塔问题大家都熟知,今天我们再次用经典的递归方法来解决它
- 有三根柱子(标记为1、2、3)和若干个大小不同的圆盘,初始时所有圆盘按从大到小的顺序堆叠在柱子1上,移动最少的步数将所有的圆盘挪到另一任意柱子上。
- 每次只能移动一个圆盘,且只能移动柱子最顶端的圆盘。
- 任何时候都不能将大盘放在小盘之上
1.解题思路
我们先来看较简单的两个圆盘怎么处理。我们先将1、2、3三个柱子分别名为F(from)、A(assist,辅助柱)、T(to):
- 将小圆盘从F移到A上
- 再将大圆盘从F移到T上
- 最后再将小圆盘从辅助柱A上移到T,完成只需三步。
那圆盘多了以后怎么办呢?
- 其实再多的圆盘也可以分为两部分,一部分是最底下的大圆盘,一部分是其上的所有圆盘。那这样也可以用处理两个圆盘的方法来解决了。
- 每次将上层部分的圆盘再分为两部分来解决,进行递归。
2.代码实现
import java.util.Scanner;public class Hanoi {public static int hanoi(int n,char F,char A,char T){ //F:from,A:assist(辅助柱),T:toint count=0;//若只有一个圆盘,则直接从当前柱挪到目标柱。if(n==1){System.out.print("第"+n+"个:"+F+"->"+T+",");count++;return count;}count+=hanoi(n-1,F,T,A);//1.将最底层上面的n-1个从F经T按规则挪到A,明显的递归体现,上层圆盘又是同类的汉诺塔问题System.out.println("第"+n+"个:"+F+"->"+T+",");//2.然后就可以将剩下来的这个最底层的直接挪到T上count++;count+=hanoi(n-1,A,F,T);//3.最后再依规则将A柱上的盘子经F挪到T上return count;//返回总移动步数}public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入圆盘数量n:");int n=sc.nextInt();int count=hanoi(n,'F','A','T');System.out.println();System.out.println("共移动了"+count+"步");}
}
3.总结
1. 基本原理:利用两个圆盘情况下的相同方法,上层F->A,底层F->T,上层再A->T2.每次上层再分解为同样两层
觉得文章对你有帮助的话就点个赞,收藏起来这份免费的资料吧!也欢迎大家在评论区讨论技术、经验
