1、题目:求 1+2+ … +n ,要求不能使用乘除法、 for 、 while 、 if 、 else 、 switch 、 case 等关键字以及条件判断语句( A?B:C )。
方法1:针对循环可以用递归来替代。(用了if)
整个代码:
int add(int n){
if(n==1) return n;
else{
return n+add(n-1);}}
#define T(X, Y, i) (Y &(1<<i)) && (X+=(Y<<i))
int foo(int n){
int r=n;
T(r, n, 0); T(r, n,1); T(r, n, 2); …T(r, n, 31);
return r >> 1;
}
//这个方法思路是将n看做是2位进制数,然后从低位到高位循环,如果当前位为1且(假设当前位是第i位)则将n的左移i位的值进行累加。也就是利用了位操作和位操作来实现求一个数的平方。
例如:
求100的平方:
100对应的二进制为:01100100
那么从右边开始向左移位(位置从0开始计数),分别发现第2,5,6位是1那么就将100左移2,5,6之后的数累加起来,实际上是100分别乘以:2^2=4,2^5=32,2^6=64,的结果进行累加,而这个累加实质就是100*(4+32+64)=100*100也就是100的平方。但它的确没有用到乘法,实在是妙不可言呀。
而我们要的结果是n^2+n,那么可以在累加前将存储累加中间结果的变量初始化为n(比如在上面代码中r初始为n),这样再进行累加就可以得到n^2+n了。
2、求二叉树中节点最大的距离
有两种情况,要么是树的深度(例如链表的情况),要么是两个子树的深度和加2。最终的结果要么来自某个子树的最大距离,要么来自两个子树的深度和加2。
//求树的深度
int height(BinTree* root){
int lheight,rheight;
if(root->lchild){
lheight=1+height(root->lchild);}
if(root->rchild){
rheight=1+height(root->rchild);}
return max(lheight,rheight);
}
int maxdistance(BinTree* root){
if(root->lchild==null || root->rchild==null)
{
return height(root);//若左子树或者右子树为空,即为树高度
}
else{
return height(root->lchild)+height(root->rchild)+2; //左右子树都不为空时,为左子树与右子树高度之和再加2
}
}
3、输入一个已经排好序的数组和一个数字,在数组中找两个数字,是的他们的和正好等于输入的数字,要求时间复杂度为O(n)。若有多对数字的和等于输入的数字,输出任意一对即可。
如:输入1、2、4、7、11和15,输出4+11=15.
分析:使用两个指针分别从数组的起始low和终止位置high开始,若两者之和小于输入的值,则增加low,反之减小high。
static void find2Numbers(int[] a,int m){
int low=0,high=a.length-1;
while(low<high){
if(a[low]+a[high]<m){
low++;
}
else if(a[low]+a[high]>m){
high--;
}
else{
System.out.println(a[low]+"+"+a[high]+"="+m);
break;
}
}
}
4、不使用加减乘除运算符号来实现两个整数的加法、减法、乘法、除法
加法、减法
int A, B;
A&B //看哪几位有进位
A^B //不带进位加
将减法直接视作正数与负数相加,而计算机中负数直接取其正数的补码,即和加法操作一样。
static int Add(int a, int b)
{
int sum = a ^ b;
int carry = a & b;
while (carry != 0) {
a = sum;
b = carry << 1;
sum = a ^ b;
carry = a & b;
}
return sum;
}
乘法
如果可以使用“+”,题1中的解法即可。