diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\270\200\344\270\252\346\225\260\346\230\257\345\220\246\344\270\2724\347\232\204n\346\254\241\346\226\271.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\270\200\344\270\252\346\225\260\346\230\257\345\220\246\344\270\2724\347\232\204n\346\254\241\346\226\271.java" new file mode 100644 index 0000000..298bb88 --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\270\200\344\270\252\346\225\260\346\230\257\345\220\246\344\270\2724\347\232\204n\346\254\241\346\226\271.java" @@ -0,0 +1,16 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 一个数是否为4的n次方 { + + public boolean isPowerOfFour(int num) { + if (num < 0) return false; + //保证这个数只有1个1并且1后面只有偶数个0,也就是1在奇数位上 + if (Integer.bitCount(num) == 1 && Integer.numberOfTrailingZeros(num) % 2 == 0) { + return true; + } + return false; + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\270\200\344\270\252\346\225\260\346\230\257\345\220\246\346\230\2572\347\232\204n\346\254\241\346\226\271.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\270\200\344\270\252\346\225\260\346\230\257\345\220\246\346\230\2572\347\232\204n\346\254\241\346\226\271.java" new file mode 100644 index 0000000..4a1c767 --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\270\200\344\270\252\346\225\260\346\230\257\345\220\246\346\230\2572\347\232\204n\346\254\241\346\226\271.java" @@ -0,0 +1,19 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 一个数是否是2的n次方 { + //2的n次方的二进制表示只有1个1 + public boolean isPowerOfTwo(int n) { + if (n < 0) return false; + if (Integer.bitCount(n) == 1) { + return true; + }return false; + } +// 利用 1000 & 0111 == 0 这种性质,得到以下解法: +// +// public boolean isPowerOfTwo(int n) { +// return n > 0 && (n & (n - 1)) == 0; +// } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\270\215\347\224\250\351\242\235\345\244\226\345\217\230\351\207\217\344\272\244\346\215\242\344\270\244\344\270\252\346\225\264\346\225\260.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\270\215\347\224\250\351\242\235\345\244\226\345\217\230\351\207\217\344\272\244\346\215\242\344\270\244\344\270\252\346\225\264\346\225\260.java" new file mode 100644 index 0000000..809b3c8 --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\270\215\347\224\250\351\242\235\345\244\226\345\217\230\351\207\217\344\272\244\346\215\242\344\270\244\344\270\252\346\225\264\346\225\260.java" @@ -0,0 +1,12 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 不用额外变量交换两个整数 { + public void swap (int a,int b) { + a = a ^ b; + b = b ^ a; + a = a ^ b; + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\275\215\350\277\220\347\256\227\345\237\272\347\241\200.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\275\215\350\277\220\347\256\227\345\237\272\347\241\200.java" new file mode 100644 index 0000000..46f48ef --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\344\275\215\350\277\220\347\256\227\345\237\272\347\241\200.java" @@ -0,0 +1,46 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 位运算基础 { +// 位运算 +// +//1. 基本原理 +// +//0s 表示一串 0,1s 表示一串 1。 +// +// x ^ 0s = x x & 0s = 0 x | 0s = x +// x ^ 1s = ~x x & 1s = x x | 1s = 1s +// x ^ x = 0 x & x = x x | x = x +// 利用 x ^ 1s = ~x 的特点,可以将位级表示翻转;利用 x ^ x = 0 的特点,可以将三个数中重复的两个数去除,只留下另一个数。 +// 利用 x & 0s = 0 和 x & 1s = x 的特点,可以实现掩码操作。一个数 num 与 mask :00111100 进行位与操作,只保留 num 中与 mask 的 1 部分相对应的位。 +// 利用 x | 0s = x 和 x | 1s = 1s 的特点,可以实现设值操作。一个数 num 与 mask:00111100 进行位或操作,将 num 中与 mask 的 1 部分相对应的位都设置为 1。 +// 位与运算技巧: +// +// n&(n-1) 去除 n 的位级表示中最低的那一位。例如对于二进制表示 10110 100 ,减去 1 得到 10110011,这两个数相与得到 10110000。 +// n-n&(~n+1) 去除 n 的位级表示中最高的那一位。 +// n&(-n) 得到 n 的位级表示中最低的那一位。-n 得到 n 的反码加 1,对于二进制表示 10110 100 ,-n 得到 01001100,相与得到 00000100 +// 移位运算: +// +// >> n 为算术右移,相当于除以 2n; +// >>> n 为无符号右移,左边会补上 0。 +// << n 为算术左移,相当于乘以 2n。 + + +// 2. mask 计算 +// +// 要获取 111111111,将 0 取反即可,~0。 +// +// 要得到只有第 i 位为 1 的 mask,将 1 向左移动 i-1 位即可,1<<(i-1) 。例如 1<<4 得到只有第 5 位为 1 的 mask :00010000。 +// +// 要得到 1 到 i 位为 1 的 mask,1<<(i+1)-1 即可,例如将 1<<(4+1)-1 = 00010000-1 = 00001111。 +// +// 要得到 1 到 i 位为 0 的 mask,只需将 1 到 i 位为 1 的 mask 取反,即 ~(1<<(i+1)-1)。 + +// 3. Java 中的位操作 +// +// static int Integer.bitCount(); // 统计 1 的数量 +// static int Integer.highestOneBit(); // 获得最高位 +// static String toBinaryString(int i); // 转换为二进制表示的字符串 +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\345\210\244\346\226\255\344\270\200\344\270\252\346\225\260\347\232\204\344\275\215\347\272\247\350\241\250\347\244\272\346\230\257\345\220\246\344\270\215\344\274\232\345\207\272\347\216\260\350\277\236\347\273\255\347\232\2040\345\222\2141.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\345\210\244\346\226\255\344\270\200\344\270\252\346\225\260\347\232\204\344\275\215\347\272\247\350\241\250\347\244\272\346\230\257\345\220\246\344\270\215\344\274\232\345\207\272\347\216\260\350\277\236\347\273\255\347\232\2040\345\222\2141.java" new file mode 100644 index 0000000..f16c793 --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\345\210\244\346\226\255\344\270\200\344\270\252\346\225\260\347\232\204\344\275\215\347\272\247\350\241\250\347\244\272\346\230\257\345\220\246\344\270\215\344\274\232\345\207\272\347\216\260\350\277\236\347\273\255\347\232\2040\345\222\2141.java" @@ -0,0 +1,18 @@ +package 数据结构.位运算; + +import java.lang.reflect.Parameter; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 判断一个数的位级表示是否不会出现连续的0和1{ + public boolean hasAlternatingBits(int n) { + while (n != 0) { + if (((n >> 1) & 1) == (n & 1)) { + return false; + } + n >>= 1; + } + return true; + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\345\255\227\347\254\246\344\270\262\346\225\260\347\273\204\346\234\200\345\244\247\344\271\230\347\247\257.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\345\255\227\347\254\246\344\270\262\346\225\260\347\273\204\346\234\200\345\244\247\344\271\230\347\247\257.java" new file mode 100644 index 0000000..4ef10db --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\345\255\227\347\254\246\344\270\262\346\225\260\347\273\204\346\234\200\345\244\247\344\271\230\347\247\257.java" @@ -0,0 +1,28 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 字符串数组最大乘积 { + public int maxProduct(String[] words) { + int n = words.length; + int[] val = new int[n]; + //用一个二进制数来存储一个数所包含的字母种类。 + //32位可以容纳26个字母,用数组保存n个二进制数,两两相与,如果结果为0 + //说明这两个数没有重复的字母,可以返回。 + for (int i = 0; i < n; i++) { + for (char c : words[i].toCharArray()) { + val[i] |= 1 << (c - 'a'); + } + } + int ret = 0; + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + if ((val[i] & val[j]) == 0) { + ret = Math.max(ret, words[i].length() * words[j].length()); + } + } + } + return ret; + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\211\276\345\207\272\346\225\260\347\273\204\344\270\255\347\274\272\345\244\261\347\232\204\351\202\243\344\270\252\346\225\260.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\211\276\345\207\272\346\225\260\347\273\204\344\270\255\347\274\272\345\244\261\347\232\204\351\202\243\344\270\252\346\225\260.java" new file mode 100644 index 0000000..7dd632f --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\211\276\345\207\272\346\225\260\347\273\204\344\270\255\347\274\272\345\244\261\347\232\204\351\202\243\344\270\252\346\225\260.java" @@ -0,0 +1,20 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 找出数组中缺失的那个数 { + //和找唯一数一样的思路,数组中的数全部异或,再和1-n的所有数异或。 + //最后的结果就是缺少的那个数 + public int missingNumber(int[] nums) { + int n = nums.length; + int res = 0; + for (int i : nums) { + res = res ^ i; + } + for (int i = 0;i <= n;i ++) { + res = res ^ i; + } + return res; + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\211\276\345\210\260\344\273\205\346\234\211\347\232\204\344\270\244\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\346\225\260.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\211\276\345\210\260\344\273\205\346\234\211\347\232\204\344\270\244\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\346\225\260.java" new file mode 100644 index 0000000..d9fc82e --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\211\276\345\210\260\344\273\205\346\234\211\347\232\204\344\270\244\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\346\225\260.java" @@ -0,0 +1,25 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 找到仅有的两个不重复的数 { + public int[] singleNumber(int[] nums) { + int res = 0; + for (int i : nums) { + res = res ^ i; + } + int []arr = new int[2]; + //取到两个不同数异或结果的最右的1。比如0001000 + res = res & (-res); + //两个数在这个位上1个为0一个为1,异或后分别得到两个数 + for (int i : nums) { + if ((res & i) == 0) { + arr[0] ^= i; + }else { + arr[1] ^= i; + } + } + return arr; + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\225\260\347\273\204\344\270\255\345\224\257\344\270\200\344\270\200\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\345\205\203\347\264\240.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\225\260\347\273\204\344\270\255\345\224\257\344\270\200\344\270\200\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\345\205\203\347\264\240.java" new file mode 100644 index 0000000..cccb587 --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\225\260\347\273\204\344\270\255\345\224\257\344\270\200\344\270\200\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\345\205\203\347\264\240.java" @@ -0,0 +1,15 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 数组中唯一一个不重复的元素 { + public int singleNumber(int[] nums) { + int res = 0; + //相同的元素异或得0,0和唯一的一个元素异或得到该元素 + for (int i : nums) { + res = res ^ i; + } + return res; + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\225\264\346\225\260\345\212\240\346\263\225.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\225\264\346\225\260\345\212\240\346\263\225.java" new file mode 100644 index 0000000..7b10637 --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\225\264\346\225\260\345\212\240\346\263\225.java" @@ -0,0 +1,10 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 整数加法 { + public int getSum(int a, int b) { + return b == 0 ? a : getSum((a ^ b), (a & b) << 1); + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\261\202\344\270\200\344\270\252\346\225\260\347\232\204\350\241\245\347\240\201.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\261\202\344\270\200\344\270\252\346\225\260\347\232\204\350\241\245\347\240\201.java" new file mode 100644 index 0000000..5290274 --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\346\261\202\344\270\200\344\270\252\346\225\260\347\232\204\350\241\245\347\240\201.java" @@ -0,0 +1,57 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 求一个数的补码 { + + +// ///题目描述:不考虑二进制表示中的首 0 部分。 +// +// 对于 00000101,要求补码可以将它与 00000111 进行异或操作。那么问题就转换为求掩码 00000111。 +// +// public int findComplement(int num) { +// if (num == 0) return 1; +// int mask = 1 << 30; +// while ((num & mask) == 0) mask >>= 1; +// mask = (mask << 1) - 1; +// return num ^ mask; +// } +// 可以利用 Java 的 Integer.highestOneBit() 方法来获得含有首 1 的数。 +// +// public int findComplement(int num) { +// if (num == 0) return 1; +// int mask = Integer.highestOneBit(num); +// mask = (mask << 1) - 1; +// return num ^ mask; +// } +// 对于 10000000 这样的数要扩展成 11111111,可以利用以下方法: +// +// mask |= mask >> 1 11000000 +// mask |= mask >> 2 11110000 +// mask |= mask >> 4 11111111 +// public int findComplement(int num) { +// int mask = num; +// mask |= mask >> 1; +// mask |= mask >> 2; +// mask |= mask >> 4; +// mask |= mask >> 8; +// mask |= mask >> 16; +// return (mask ^ num); +// } + + public static void main(String[] args) { + findComplement(-1); + } + public static int findComplement(int num) { + if (num >= 0) return num; + int mask = 1; + mask = Integer.MIN_VALUE; + mask -= 1; + System.out.println(Integer.toBinaryString(num)); + num = num ^ mask; + System.out.println(Integer.toBinaryString(mask)); + System.out.println(Integer.toBinaryString(num)); + return 1; + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\273\237\350\256\2411\345\210\260n\344\272\214\350\277\233\345\210\2661\347\232\204\344\270\252\346\225\260.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\273\237\350\256\2411\345\210\260n\344\272\214\350\277\233\345\210\2661\347\232\204\344\270\252\346\225\260.java" new file mode 100644 index 0000000..c2de28b --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\273\237\350\256\2411\345\210\260n\344\272\214\350\277\233\345\210\2661\347\232\204\344\270\252\346\225\260.java" @@ -0,0 +1,15 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 统计1到n二进制1的个数 { + public int[] countBits(int num) { + int cnt = 0; + int []arr = new int[num + 1]; + for (int i = 1;i <= num;i ++) { + arr[i] = Integer.bitCount(i); + } + return arr; + } +} diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\273\237\350\256\241\344\270\244\344\270\252\346\225\260\347\232\204\344\272\214\350\277\233\345\210\266\350\241\250\347\244\272\346\234\211\345\244\232\345\260\221\344\275\215\344\270\215\345\220\214.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\273\237\350\256\241\344\270\244\344\270\252\346\225\260\347\232\204\344\272\214\350\277\233\345\210\266\350\241\250\347\244\272\346\234\211\345\244\232\345\260\221\344\275\215\344\270\215\345\220\214.java" index 9333587..e499f43 100644 --- "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\273\237\350\256\241\344\270\244\344\270\252\346\225\260\347\232\204\344\272\214\350\277\233\345\210\266\350\241\250\347\244\272\346\234\211\345\244\232\345\260\221\344\275\215\344\270\215\345\220\214.java" +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\273\237\350\256\241\344\270\244\344\270\252\346\225\260\347\232\204\344\272\214\350\277\233\345\210\266\350\241\250\347\244\272\346\234\211\345\244\232\345\260\221\344\275\215\344\270\215\345\220\214.java" @@ -4,4 +4,79 @@ * Created by 周杰伦 on 2018/4/13. */ public class 统计两个数的二进制表示有多少位不同 { + //正确做法,使用异或 + public int hammingDistance(int x, int y){ + int z = x ^ y; + //异或的结果中,1所在的位就是x和y不同的位 + int cnt = 0; + while (z != 0) { + //最高位是否为1 + if ((z & 1) == 1) { + cnt ++; + //依次判断低位是否为1 + } + z = z >> 1; + } + return cnt; + } + // 正确方法2 +// 使用 z&(z-1) 去除 z 位级表示最低的那一位。 +// +// public int hammingDistance(int x, int y) { +// int z = x ^ y; +// int cnt = 0; +// while (z != 0) { +// z &= (z - 1); +// cnt++; +// } +// return cnt; +// } +// +// 方法3 这个方法补错 +// 可以使用 Integer.bitcount() 来统计 1 个的个数。 +// +// public int hammingDistance(int x, int y) { +// return Integer.bitCount(x ^ y); + + + //错误做法,使用字符串比较 +// public static int hammingDistance(int x, int y) { +// String s1 = Integer.toBinaryString(x); +// String s2 = Integer.toBinaryString(y); +// String temp; +// if (s1.length() >= s2.length()) { +// temp = s1; +// s1 = s2; +// s2 = temp; +// } +// System.out.println(s1); +// System.out.println(s2); +// int i = s1.length() - 1; +// int j = s2.length() - 1; +// int cnt = 0; +// while (i >= 0 && j >= 0) { +// if (s1.charAt(i) != s2.charAt(j)) { +// cnt ++; +// i --; +// j --; +// continue; +// } +// i --; +// j --; +// } +// while (j >= 0) { +// if (s2.charAt(j) == '1') { +// cnt ++; +// j --; +// continue; +// } +// j --; +// +// } +// return cnt; +// } +// +// public static void main(String[] args) { +// System.out.println(hammingDistance(3,1)); +// } } diff --git "a/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\277\273\350\275\254\344\270\200\344\270\252\346\225\260\347\232\204\346\257\224\347\211\271\344\275\215.java" "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\277\273\350\275\254\344\270\200\344\270\252\346\225\260\347\232\204\346\257\224\347\211\271\344\275\215.java" new file mode 100644 index 0000000..5125231 --- /dev/null +++ "b/src/\346\225\260\346\215\256\347\273\223\346\236\204/\344\275\215\350\277\220\347\256\227/\347\277\273\350\275\254\344\270\200\344\270\252\346\225\260\347\232\204\346\257\224\347\211\271\344\275\215.java" @@ -0,0 +1,17 @@ +package 数据结构.位运算; + +/** + * Created by 周杰伦 on 2018/4/27. + */ +public class 翻转一个数的比特位 { + // you need treat n as an unsigned value + public int reverseBits(int n) { + int ret = 0; + for (int i = 0; i < 32; i++) { + ret <<= 1; + ret |= (n & 1); + n >>>= 1; + } + return ret; + } +}