位运算技巧

好用的位操作

  1. class Solutions {
  2. void fun() {
  3. // 利用或操作 空格和英文字符转化小写
  4. ('a' | ' ') = 'a';
  5. ('A' | ' ') = 'a';
  6. // 利用与操作 _下划线和英文字符转化大写
  7. ('a' & '_') = 'A';
  8. ('A' & '_') = 'A';
  9. // 利用异或操作 空格和英文字符大小写互换
  10. ('a' ^ ' ') = 'A';
  11. ('A' ^ ' ') = 'a';
  12. // 判断两个数是否异号
  13. int x = -1, y = 2;
  14. boolean f = ((x ^ y) < 0); // true
  15. x = 1;
  16. y = 2;
  17. boolean f = ((x ^ y) < 0); // false
  18. // 不需要临时变量可交换两数
  19. int a = 1, b = 2;
  20. a ^= b;
  21. b ^= a;
  22. a ^= b;
  23. // 加1
  24. int n = 1;
  25. n = -~n;
  26. // 减1
  27. int m = 2;
  28. m = ~-m;
  29. }
  30. void bitOperate() {
  31. int n = 234;
  32. // 消除数字n最后一个1,n转换成二进制后最后一个数字1
  33. n & n - 1;
  34. }
  35. }

【应用示例】

  1. class Example {
  2. /**
  3. * 136
  4. * https://leetcode-cn.com/problems/single-number/
  5. * 计算数组里只出现一次的数组
  6. * 一个数字异或它本身 = 0
  7. * 一个数字异或0 = 它本身
  8. *
  9. * @param nums
  10. * @return
  11. */
  12. public int singleNumber(int[] nums) {
  13. int vis = 0;
  14. for (int i = 0; i < nums.length; i++) {
  15. vis ^= nums[i];
  16. }
  17. return vis;
  18. }
  19. /**
  20. * 231
  21. * https://leetcode-cn.com/problems/power-of-two/
  22. * 判断数字n是否是2的幂次方
  23. * n & n - 1
  24. * 数字与数字-1,消除最后一个1
  25. * 如果是幂次方,则只有一个1
  26. * @param n
  27. * @return
  28. */
  29. public boolean isPowerOfTwo(int n) {
  30. if (n <= 0) {
  31. return false;
  32. }
  33. return (n & n - 1) == 0;
  34. }
  35. /**
  36. * 191
  37. * https://leetcode-cn.com/problems/number-of-1-bits/submissions/
  38. * 计算汉明权重,算出有多少位=1
  39. * n & n - 1
  40. * 数字与数字-1,消除最后一个1
  41. * 一直到数字没有1即 = 0
  42. * @param n
  43. * @return
  44. */
  45. public int hammingWeight(int n) {
  46. int res = 0;
  47. while (n != 0) {
  48. n &= n - 1;
  49. res++;
  50. }
  51. return res;
  52. }
  53. }