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中的解法即可。