剑指Offer试题——Java实现(四)

4.1 在不使用±*/的条件下,计算两个整数相加

这里考察的就是对位运算的掌握情况
public static int addWithoutOperator(int num1,int num2){
	while(num2!=0){
		//计算个位
		int tmp=num1^num2;
		//计算进位
		num2=(num1&num2)<<1;
		num1=tmp;
	}
	return num1;
}

4.2 计算1~n的和,不得使用流程控制关键字

//所谓流程控制,也就是循环、条件判断三元表达式
//这里使用递归来代替循环
//同时使用
public static int sumSolution(int n){
	int sum=n;
	//终止递归
	boolean result=(n>0)&&((sum+=sumSolution(n-1))>0);
	return sum;
}

4.3 约瑟夫环问题

注释中的解题思路不是我的,所以附上原文链接。
好像也不是这个作者的,不过没关系,他在文章中也附上连接了。

/**
* 作者:wdg666
* 链接:https://www.zhihu.com/question/20065611/answer/148654996
* 来源:知乎
* 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*
* 假设问题是从n个人编号分别为0...n-1,取第k个,则第k个人编号为k-1的淘汰,剩下的编号为  0,1,2,3...k-2,k,k+1,k+2...此时因为从刚刚淘汰那个人的
* 下一个开始数起,因此重新编号把k号设置为0,则
* k    0
* k+1 1
* ...
* 0 n-k
* 1 n-k+1
* 假设已经求得了n-1个人情况下的最终胜利者保存在f[n-1]中,则毫无疑问,
* 该胜利者还原到原来的真正编号即为 (f[n-1]+k)%n (因为第二轮重新编号的时候,相当于把每个人的编号都减了k,因此重新+k即可恢复到原来编
* 号)。由此,我们可以想象,当最终只剩下一个人的时候,该人即为胜利者,此时重新编号,因为只有一个人,所以此时f[1]=0这样f[2]=(f[1]+k)%2,这
* 样就可以求出最终胜利者在2个人的时候的情况下的编号,由递推公式f[n]=(f[n-1]+k)%n,可递推到最初编号序列中该胜利者的编号。因此用这个方法,
* 只需一遍On的扫描,即可求出最终答案不过该题要求编号从1开始,只要把f[n]+1即可,同时,该题指定了第一个要删除的人必须为编号为m的人,其
* 实也不难,求出f[n]之后,把原本编号为0的位置移到跟m只相距k的位置即可实现第一次删除的编号为m。所以最终 ans=(f[n]+1+m-k);
*/
public static int lastRemain(int n,int m){
	if(n==0)
		return -1;
	if(n==1)
		return 0;
	else
		return (lastRemain(n-1,m)+m)%n;
}

4.4 计算输入的整数用二进制表示有多少1

/**
* n&(n-1)运算会将n的最右边一位变为0,循环x次后n变为0,则1的个数为x
*/
public static int calNumberOf1(int n){
	int count=0;
	while(n!=0){
		n=n&(n-1);
		count++;
	}
	return count;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值