a-b-problem &&/permutation-index&&count-1-in-binary
给出两个整数a和b, 求他们的和, 但不能使用 +
等数学运算符。
如果 a=1
并且 b=2
,返回3
你不需要从输入流读入数据,只需要根据aplusb
的两个参数a和b,计算他们的和并返回就行。
1 class Solution { 2 /* 3 * param a: The first integer 4 * param b: The second integer 5 * return: The sum of a and b 6 */ 7 public int aplusb(int a, int b) { 8 // write your code here, try to do it without arithmetic operators. 9 if(b==0) { 10 return a; 11 }else{ 12 return aplusb(a^b,(a&b)<<1);//a^b是进行异或运算,再加上(a&b)<<1就实现了进位 13 } 14 } 15 };
显然你可以直接 return a + b,但是你是否可以挑战一下不这样做?
排列序号
给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从1开始。
样例
例如,排列[1,2,4]是第1个排列。//这道题其实考察的是字典全排列,当然我的解法并不是正常的思路,常规的算法应该是将这个数字序列的所有字典全排列算出来,去看看所给的是第几个。
http://www.geekviewpoint.com/java/numbers/permutation_index 具体介绍见链接,
1 public class Solution { 2 /** 3 * @param A an integer array 4 * @return a long integer 5 */ 6 public long permutationIndex(int[] A) { 7 // Write your code here 8 /* long index =0; 9 long position = 2; 10 long facrtor=1; 11 for(int q = A.length-2;q >= 0; q --){ 12 long number = 0; 13 for(int p = q+1;p<q;p++) 14 }*/ 15 long index = 0; 16 long position = 2; 17 long factor = 1; 18 for (int p = A.length - 2; p >= 0; p--) { 19 long successors = 0; 20 for (int q = p + 1; q < A.length; q++) { 21 if (A[q] > A[p]) { 22 number++; 23 } 24 } 25 index += (number * factor); 26 factor *= position; 27 position++; 28 } 29 index = index + 1; 30 return index; 31 } 32 }
后续明天继续更新相关的字典排序问题
3、二进制中有多少个1
计算在一个 32 位的整数的二进制表式中有多少个 1
.
这道题在最开始的我使用的算法是通过将这个数字从最低位逐位和1做与运算,然后计算得到位数。然而这种方法并没有通过平台的测试,在91%的数据就出现了超时,因为在遇到-1这样的数字(32个1),程序的运行时间就超时。
然后我就开始百度这道题,并且发现关于这道题的算法,编程之美也有专门的介绍。看似简单的一道题其实解法还是挺多的。
1 class Solution { 2 public: 3 /** 4 * @param num: an integer 5 * @return: an integer, the number of ones in num 6 */ 7 int countOnes(int num) { 8 // write your code here 9 int count = 0; 10 11 while(num){ 12 num =num&(num-1); 13 count++; 14 } 15 return count; 16 } 17 };
问题:求一个32位2进制整数中 1的个数
1. HAKMEM算法:
1 int Count(unsigned x) 2 { 3 unsigned n; 4 5 n = (x >> 1) & 033333333333; 6 x = x - n; 7 n = (n >> 1) & 033333333333; 8 x = x - n; 9 x = (x + (x >> 3)) & 030707070707; 10 x = modu(x, 63); 11 return x; 12 }
说明:首先是将二进制各位三个一组,求出每组中1的个数,然后相邻两组归并,得到六个一组的1的个数,最后很巧妙的用除63取余得到了结果。
因为2^6 = 64,也就是说 x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod 63),这里的等号表示同余。
这个程序只需要十条左右指令,而且不访存,速度很快。
2.
1 int Count(unsigned x) 2 { 3 x = x - ((x >> 1) & 0x55555555); 4 x = (x & 0x33333333) + ((x >> 2) & 0x33333333); 5 x = (x + (x >> 4)) & 0x0F0F0F0F; 6 x = x + (x >> 8); 7 x = x + (x >> 16); 8 return x & 0x0000003F; 9 }
说明: 这里用的是二分法,两两一组相加,之后四个四个一组相加,接着八个八个,最后就得到各位之和了