您的位置:首页 > 其它

a-b-problem &&/permutation-index&&count-1-in-binary

2015-11-14 23:57 357 查看
给出两个整数a和b, 求他们的和, 但不能使用
+
等数学运算符。

样例

如果
a=1
并且
b=2
,返回
3


注意

你不需要从输入流读入数据,只需要根据
aplusb
的两个参数a和b,计算他们的和并返回就行。

[b]挑战[/b]

class Solution {
/*
* param a: The first integer
* param b: The second integer
* return: The sum of a and b
*/
public int aplusb(int a, int b) {
// write your code here, try to do it without arithmetic operators.
if(b==0) {
return a;
}else{
return aplusb(a^b,(a&b)<<1);//a^b是进行异或运算,再加上(a&b)<<1就实现了进位
}
}
};


显然你可以直接 return a + b,但是你是否可以挑战一下不这样做?

排列序号

给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从1开始。

样例

例如,排列[1,2,4]是第1个排列。//这道题其实考察的是字典全排列,当然我的解法并不是正常的思路,常规的算法应该是将这个数字序列的所有字典全排列算出来,去看看所给的是第几个。
http://www.geekviewpoint.com/java/numbers/permutation_index 具体介绍见链接,

public class Solution {
/**
* @param A an integer array
* @return a long integer
*/
public long permutationIndex(int[] A) {
// Write your code here
/* long index =0;
long position = 2;
long facrtor=1;
for(int q = A.length-2;q >= 0; q --){
long number = 0;
for(int p = q+1;p<q;p++)
}*/
long index = 0;
long position = 2;
long factor = 1;
for (int p = A.length - 2; p >= 0; p--) {
long successors = 0;
for (int q = p + 1; q < A.length; q++) {
if (A[q] > A[p]) {
number++;
}
}
index += (number * factor);
factor *= position;
position++;
}
index = index + 1;
return index;
}
}


后续明天继续更新相关的字典排序问题

3、二进制中有多少个1

计算在一个 32 位的整数的二进制表式中有多少个
1
.

这道题在最开始的我使用的算法是通过将这个数字从最低位逐位和1做与运算,然后计算得到位数。然而这种方法并没有通过平台的测试,在91%的数据就出现了超时,因为在遇到-1这样的数字(32个1),程序的运行时间就超时。

然后我就开始百度这道题,并且发现关于这道题的算法,编程之美也有专门的介绍。看似简单的一道题其实解法还是挺多的。

class Solution {
public:
/**
* @param num: an integer
* @return: an integer, the number of ones in num
*/
int countOnes(int num) {
// write your code here
int count = 0;

while(num){
num =num&(num-1);
count++;
}
return count;
}
};


问题:求一个32位2进制整数中 1的个数

1. HAKMEM算法:

int Count(unsigned x)
{
unsigned n;

n = (x >> 1) & 033333333333;
x = x - n;
n = (n >> 1) & 033333333333;
x = x - n;
x = (x + (x >> 3)) & 030707070707;
x = modu(x, 63);
return x;
}


说明:首先是将二进制各位三个一组,求出每组中1的个数,然后相邻两组归并,得到六个一组的1的个数,最后很巧妙的用除63取余得到了结果。

因为2^6 = 64,也就是说 x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod 63),这里的等号表示同余。

这个程序只需要十条左右指令,而且不访存,速度很快。

2.

int Count(unsigned x)
{
x = x - ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x = x + (x >> 8);
x = x + (x >> 16);
return x & 0x0000003F;
}


说明: 这里用的是二分法,两两一组相加,之后四个四个一组相加,接着八个八个,最后就得到各位之和了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: