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(纹理坐 ...
随机推荐
- 【OSG细节实现】节点围绕位于axisPos平行于axis的轴进行旋转
//绕着与axis平行的任意轴旋转 void rotate(const std::string& name, float angle, osg::Vec3 axisPos, osg::Vec3 ...
- 3月3日(5) Roman to Integer
原题 Roman to Integer 题意很简单,把Roman字母翻译成int. 实现方式也不难,针对每个字符转成int,从右往左,依次判断,如果当前值比上一个值大则相加,小则相减. 什么,你问我怎 ...
- 基于OCILIB的oracle数据库操作总结及自动生成Model和Dao的工具
基于OCILIB的oracle数据库操作总结 1. 类图 2. 基类BaseOCIDao的设计与实现 BaseOCIDao.h头文件 #pragma once /* ----- ...
- Linux磁盘与文件系统概念理解
磁盘级别概念 这里讲的主要是网上所谓的老式磁盘,它是由一个个盘片组成的,我们先从个盘片结构讲起.如图1所示,图中的一圈圈灰色同心圆为一条条磁道,从圆心向外画直线,可以将磁道划分为若干个弧段,每 ...
- dmp文件导入
dmp文件导入 1,打开“开始”-->输入cmd—> sqlplus log: 2,输入 conn / as sysdba管理员账户登录: 3,需要创建表空间,如果我们知道需要导入的数据库 ...
- EventHandler委托的使用
今天复习了一下事件和委托,本来看事件来着,看到EventHandler,写了一个小例子,想贴在这里解释一下.为了弄清楚EventHandler, 还是回归到最基本的委托,曾经在园子里看到一位前辈用深入 ...
- php strpos 用法实例教程
定义和用法该strpos ( )函数返回的立场,首次出现了一系列内部其他字串. 如果字符串是没有发现,此功能返回FALSE . 语法 strpos(string,find,start) Paramet ...
- linux 文件属性
关于属性的结构 在linux下文件和文件夹都被认为是文件, 所以以下的这个属性对文件和文件夹通用 获取属性的函数有stat/fstat/lstat/fstat struct stat{ mode_t ...
- JMS消息头
一个消息对象分为三部分:消息头(Headers),属性(Properties)和消息体(Payload).对于StreamMessage和MapMessage,消息本身就有特定的结构,而对于TextM ...
- 流水线(pipe-line)简介
1.什么是流水线设计技术? 答:所谓流水线设计实际上是把规模较大.层次较多的组合逻辑电路分为几个级,在每一级插入寄存器组并暂存数据. K级就是有K个寄存器组,从上到下没有反馈电路. 2.流水线设计的深 ...