Offer之路
来源:互联网 发布:linux配置网关命令 编辑:程序博客网 时间:2024/05/16 01:34
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);}}
方法2:利用数学知识其实当在处理数组之类问题,利用数学知识去考虑,也是一种思路。
分析:
1+2+...+n=(n^2+n)/2,首先除以2很容易解决右移1位即可,重点在于求n^2。
n^2=n*n;将n分解成2^0,2^1,2^2,...相加的形式。例如100^2=100*100=100*(64+32+4)=100*2^6+100*2^5+100*2^2,也就是将100左移6位、5位、2位产生的3个结果分别相加即可。当然这样的分配也不是随机的。
#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中的解法即可。
- Offer之路
- 我的阿里巴巴offer之路
- 剑指OFFER之链表篇
- 剑指OFFER之队列
- 剑指offer之数据结构
- 剑指offer之数组
- 剑指offer之斐波拉契
- 剑指offer之链表篇
- 剑指offer之树
- 剑指offer之查找
- 我的阿里秋招之路——阿里实习offer+校招offer
- 2104腾讯暑期实习offer之路(技术类面经)
- 剑指OFFER之栈篇
- 剑指OFFER之数组篇
- 剑指Offer之替换空格
- 剑指Offer之二叉树重构
- 剑指Offer之 - 丑数
- 剑指Offer之 - 替换空格
- 体积着色器(Volume Shader)
- word中图片的处理
- 欢迎大家访问吐槽人网 http://www.tucaoman.com/
- poj2771二分图点权最大独立集,用Dinic解决
- Android手机使用笔记本流量上网(基于Android便携式WLAN热点)
- Offer之路
- centos+nginx+php+apc+percona
- 指针也可这么玩:返回局部指针变量,局部噢
- 系统调用VS库函数
- 【thinkphp3.x】thinkphp3.x中Action参数绑定
- ★★输入数据个数未知,如何动态输入 C/C++
- 不可不看!真正专业显卡技术分析评测
- 如何update sql 批量更新(sql server)
- android语音识别