#Leetcode 题目记录:231,342,191, 190,172,258,292
这些题其实大多数都是一些数学的小技巧,以及一些数论的知识,我把他们归纳到一起,整理好,方便以后复习
190. 例43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000). * solution:231: 2的幂转换成二进制都是10,100,1000*,所以可以通过位运算100和011的并来判断是否为0 * 191 342 见代码 * * 326 求3的幂,一般方法,假设m大于n的3的幂,也即m=3^? > n=3^?; 则m % n==0 * 所以我们求在int范围内最大的3的幂,%n 就行,也就是我们求最大的k,使得3^k 在int范围里最大,然后 %n * * 190 要求二进制翻转,那么我们可以通过&1 右移来判断每一位是否为1,然后通过左移来实现 * 这些题着重在于考虑位运算的与非操作,同时将变量换为二进制 * * 172 求n!末尾连续多少个零 n = 1*2*3*4*5.... 又因为10是2和5的乘积,零的数量是最小值2和数量5(因为2的数量大于5) * n=2*3*4*5*...*(5^1*2)*....*(5^1*3)..2,所以我们只计算从1到n的所有数字中有多少个5, * 5的倍数在1到23之间有5,10,15和20,23!有4个零。 * 但是注意25是5×5,所以25的每个倍数有5的额外因子,例如25×4 = 100,这引起了额外的零。 * 所以,我们需要知道25的倍数在1到100,由于100÷25 = 4,在1到100之间有25的倍数。 * 同样当一个数比较大时还是要知道125,625等 * * 258 num = 38:3 + 8 = 11,1 + 1 = 2。由于2只有一位,返回。下面是我的一般方法,时间复杂度为O(n) * ab = a*10+b ab%9=(a*9+a+b)%9 =(a+b)%9 * abc = a*100+b*10+c abc%9=(a*99+b*9+a+b+c)%9 = (a+b+c)%9 * 但是注意啊,%9的范围只能是[0,8],比如18%9=0; 所以我们可以(n-1)%9=(a+b+c-1)%9 然后在加一 * (n-1)%9+1 * 所以有更简单的方法,时间复杂度更低 * * 292 Nim游戏:桌上有一堆石头,每次你们轮流去掉1到3块石头。去掉最后一块石头的人将是胜利者。你会采取第一回合去除石头。 * 这里注意一个定理:第一个获得4的倍数(即n%4 == 0)的人输,否则将获胜。1,2,3-true 4-false, 5,6,7-true 8-false * 因为如果有8个,你第一次不论拿几个,只要第一轮给你留下来4个,你就必输 * 如果有9,10,11个,你只要给它留下来8个,你就必赢 */ import com.sun.org.apache.xpath.internal.SourceTree; import static java.lang.Math.log; import static java.lang.Math.pow; public class PowerOfTwoAndOthers { static final int maxint = 0x7fffffff;//static 不能修饰局部变量。也就是说方法里不能定义static变量,java定义常量 static final int minint = 0x80000000; //leetcode 231 public static boolean isPowerOfTwo(int n){ if(n <= 0) return false; return ((n&(n-1)) == 0); //位运算 } //leetcode 342 public static boolean isPowerOfFour(int n){ //0x5 0101 //0x55 0101 0101 。。。0x55555555 0101*(8) //刚好用来筛选2 8 32 。。10 1000 100000 //4 16 64 。。 100 100000 10000000 //0101 & 100(4) = 100 //0101 & 1000(8) = 0 if(n <= 0) return false; return (((n&(n-1)) == 0) && ((n&0x55555555) != 0)); } //leetcode 326 public static boolean isPowerOfThree(int n) { if( n <= 0) return false; int k = (int) (log(maxint) / log(3)); int m = (int) pow(3,k); return (m % n == 0); } //leetcode 191 public static int Numberof1Bits(long n){ int cout=0; // 循环判断每一位是否为1,还有一种方法是n&(n-1),但是要求是无符号整型java里是没有这种数据类型的 for(int i=0; i<=31; i++){ if((n&(int)(pow(2,i))) != 0){ cout += 1; } } //因为是无符号整形,也就是说还有21474834648这个数字,考虑边界范围 if(n == 0x80000000L){ return 1; } /* 其实这个方法是最好的,每次判定结束就右移一位。 Java中的整数具有32位,例如00101000011110010100001000011010。 要计算Integer表示中的1,我们输入int n与位1和1(表示为 00000000000000000000000000000001,如果此操作结果为1, 这意味着输入整数的最后一位为1.因此,我们将其添加到1s计数。one = ones +(n&1); 在Java中,我们需要注意的是最大的整数是2147483647.Java中的整数类型是有符号的,没有unsigned int。 所以输入2147483648用Java表示为-2147483648(在java int类型中有一个循环表示,这意味着Integer.MAX_VALUE + 1 == Integer.MIN_VALUE)。 int ones = 0; while(n!=0) { ones = ones + (n & 1); n = n>>>1; } return ones; */ return cout; } //leetcode 172 public static int trailingZeroes(int n) { int sum = 0; while(n > 0){ sum = sum + n /5; n = n / 5; } return sum; } //leetcode 190 public static int reverseBits(int n) { int result = 0; for(int i = 0; i < 32; i++){ result = result + (n & 1);//位运算优先级最低 n = n >>> 1; if(i < 31) result = result << 1; //当i=31时,已经是32位了,所以不能在左移了 } return result; } //leetcode 258 public int addDigits(int n) { /* * if(n == 0) return 0; * return (n-1)%9+1 * */ int m = 0; if(n == 0) return 0; while(n != 0){ m = n % 10 + m; n /= 10; } if( m / 10 != 0){ m = addDigits(m); } return m; } //leetcode 292 public boolean canWinNim(int n) { if(n % 4 == 0) return false; else return true; } public static void main(String[] args) { // TODO Auto-generated method stub //二进制转换 int a = 120;//定义一个变量并赋给他一个十进制的值 int remainder;//定义一个变量用于存储余数 int sum = 0;//定义一个变量用于存放和 int k = 1;//定义一个变量控制位数 while(a != 0){ remainder = a % 2;//对目标数字求余 a /= 2;//对目标数字求商 sum = sum + remainder * k;//求和 k *= 10;//改变位数 } boolean b = PowerOfTwoAndOthers.isPowerOfTwo(1); boolean c = PowerOfTwoAndOthers.isPowerOfFour(64); boolean d = PowerOfTwoAndOthers.isPowerOfThree(81); long nn = 2147483648L; int nnn = PowerOfTwoAndOthers.reverseBits(43261596); System.out.println(nn); int n = PowerOfTwoAndOthers.Numberof1Bits(2147483648L); System.out.println(b); System.out.println(n); System.out.println(d); System.out.println("10进制的123转换为2进制结果为:" + sum ); System.out.println("nnn==" + nnn); System.out.println(PowerOfTwoAndOthers.trailingZeroes(98)); } }