Chp18: Hard
18.1 Write a function that adds two numbers. You should not use + or any arithmetic operators.
Solution: deal with 759 + 674.
1. add 759 + 674, but forget to carry. get 323
2. add 759 + 674, but only do the carrying, rather than the addition of each digit. get 1110
3. add the result of the first two operations(recursively): 1110 + 323 = 1433
public int add(int a, int b){
if(b == 0) return a;
if(a == 0) return b;
int sum = a ^ b; // 1
int ope = (a & b) << 1; // 2
return add(sum, ope);
}
18.3 Write a method to randomly generate a set of m integers from an array of size n. Each element must have equal probability of being chosen.
Solution: shrink the array to no longer contain elements that already chosen.
public int[] pickMRandomly(int[] original, int m){
int[] result = new int[m];
int array = original.clone(); // 必须要先复制出来,否则会更改原来数组的结构
for(int j = 0; j < m; j ++){
int index = random(j, array.length - 1);
result[j] = array[index];
array[index] = array[j];
}
return result;
}
18.6 Describe an algorithm to find the smallest one million numbers in one billion numbers. Assume that the computer memory can hold all one billion numbers.
Selection Rank Algorithm: find the ith smallest (or largest) element in an array in linear time.
If the elements are unique, can find it in O(n).
1.pick a random element in the array and use it as a "pivot". Partition elements around the pivot, keep track of the number of elements on the left side of the partition.
2.if there are exactly i elements on the left, then you just return the biggest element on the left.
3.if the left side is bigger than i, repeat the algo on just the left part of the array.
4.if the left side is smaller than i, repeat the algo on the right, but look for the lement with rank i - leftsize.
public int partition(int[] array, int left, int right, int pivot){
while(true){
while(left <= right && array[left] <= pivot) left ++;
while(left <= right && array[right] > pivot) right --;
if(left > right) return left - 1;
swap(array, left, right);
}
}
public int rank(int[] array, int left, int right, int rank){
int pivot = array[randomIntInRange(left, right)];
int leftEnd = partition(array, left, right, pivot);
int leftSize = leftEnd - left + 1;
if(leftSize == rank + 1) return max(array, left, leftEnd);
else if(rank < leftSize) return rank(array, left, leftEnd, rank);
else return rank(array, leftEnd + 1, right, rank - leftSize);
}
Chp18: Hard的更多相关文章
- [图形学] Chp18 OpenGL表面纹理函数
以2D表面为例展示纹理贴图,用opengl设置一个2D纹理,颜色存储在32*32*3的数组中,对应的纹理坐标为0<=s, t<=1.0. 画出几个正方形表面,分别以GL_CLAMP(纹理坐 ...
随机推荐
- 分享9款很有创意的HTML5动画
1.HTML5 SVG Loading 动画加载特效 这是一款基于HTML5/CSS3和SVG的Loading加载动画特效,一共有4种不同的动画效果.每一组Loading动画都非常可爱,他们都非常欢快 ...
- JavaScript选项卡
实现js选项卡 html的代码如下: <div class="tabdiv"> <ul class="tabs" id="oTab& ...
- 《linux文件权限管理大总结》RHEL6
在linux系统下文件的权限通常会以下面的格式显示出来: Chmod文件权限: 权限的管理chmod -a 所有的权限 -u 文件所有者的权限 -g 组权限 -o 其他用户的权限 可以使用运算符来设 ...
- 初识NoSQL 快速认识NoSQL数据库 分析Analytics For Hackers: How To Think About Event Data
做了一年的大一年度项目了,对于关系型数据库结构还是有些了解了,有的时候还是觉得这种二维表不是很顺手.在看过一篇文章之后,对NoSQL有了初步的了解,(https://keen.io/blog/5395 ...
- centos 减少tty数量的方法
在linux中,包括本文介绍的centos系统中,tty系统默认是给出7个,前六个是terminal,一个用于X. 在centos5.x中减少tty数量,通过修改/etc/inittab来实现. [r ...
- C# CacheHepler Class
internal class CacheHelper { /// <summary> /// Insert value into the cache using /// appropria ...
- Mysql备份--mysqldump&outfile
1.备份工具mysqldump 客户端和服务器端都能用select outfile 只能写到服务器端 2.按表单位备份 a.单个表备份 mysqldump -uusername -p database ...
- Png图片的透明部分穿透测试
private void Window_MouseMove(object sender, MouseEventArgs e){ NavBtnList.Clear(); Point mou ...
- GITHUB 提交错误 Error: Permission denied (publickey) 解决
1. 在开发机上生成自己的密钥 ssh-keygen -b 1024 -t rsa -b 指密钥对长度 -t 指加密方式 Enter file in which to save the key ( ...
- 含有自增序列的表中使用truncate与delete的不同结果
一个含有自增序列的表,使用delete跟truncate之后会有什么不同结果呢? 大概说一下,使用truncate,表中的记录全部被清除,如果向表中插入数据,那么数据的排序是从1开始的. 如果使用的是 ...