栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

搜索算法、回溯算法、位运算、二分查找 6/11 56-60

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

搜索算法、回溯算法、位运算、二分查找 6/11 56-60

1.比特位计数( LeetCode 338 )

方法一:逐一计算
时间复杂度 O(n log n)

class Solution {
     public int[] countBits(int n) {
            int[] ans = new int[n + 1];
            for (int i = 0; i <= n; i++) {
                int a = i;
                int b = 0;
                int count = 0;//计数器
                while (a != 0){//计算二进制中1的个数
                    b = a & 1;//b为二进制中的最后一个数字
                    if (b == 1)count++;
                    a = a >> 1;
                }
                ans[i] = count;
            }
            return ans;
        }
}

方法二:方法一的另一种写法

class Solution {
    public int[] countBits(int n) {
        int[] bits = new int[n + 1];
        for (int i = 0; i <= n; i++) {
            bits[i] = countOnes(i);
        }
        return bits;
    }

    public int countOnes(int x) {
        int ones = 0;
        while (x > 0) {
            x &= (x - 1);// x & (x - 1)用来抹除x二进制中最后的一个1
            ones++;
        }
        return ones;
    }
}

方法三:使用内置函数

 class Solution {
        public int[] countBits(int n) {
          int[] ans = new int[n + 1];
            for (int i = 0; i <= n; i++) {
                //使用内置函数计算 i 的二进制表示中1的位数
                ans[i] = Integer.bitCount(i);
            }
            return ans;
        }
    }

方法四:动态规划 最高有效位

class Solution {
        
        public int[] countBits(int n) {
            int[] ans = new int[n + 1];
            int height = 0;
            for (int i = 1; i <= n; i++) {
                if ((i & (i - 1)) == 0) {
                    height = i;
                }
                ans[i] = ans[i - height] + 1;
            }
            return ans;
        }
    }

方法五:动态规划 最低有效位

  class Solution {
        
        public int[] countBits(int n) {
            int[] ans = new int[n + 1];
            for (int i = 0; i <= n; i++) {
                ans[i] = ans[i >> 1] + (i & 1);
            }
            return ans;
        }
    }

方法六:动态规划 最低设置位
与方法五对照着思考

class Solution {
    public int[] countBits(int n) {
        int[] bits = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            bits[i] = bits[i & (i - 1)] + 1;
        }
        return bits;
    }
}
2.位 1 的个数( LeetCode 191 )

方法一:循环检查二进制位

public class Solution {
    public int hammingWeight(int n) {
        int ret = 0;
        for (int i = 0; i < 32; i++) {
            if ((n & (1 << i)) != 0) {
                ret++;
            }
        }
        return ret;
    }
}

方法二:位运算优化

public class Solution {
   // you need to treat n as an unsigned value
   public int hammingWeight(int n) {
        int ans = 0;
        while (n != 0){
            n = n & (n - 1);
            ans++;
        }
        return ans;
    }
}

错误解法

public int hammingWeight(int n) {
        int ans = 0;
        while (n != 0){
            int x = n & 1;
            if (x == 1)ans++;
            //正数与负数右移规则不同,此处不适用
            n = n >> 1;
        }
        return ans;
    }
3.只出现一次的数字 II( LeetCode 137 )

方法一:排序 暴力解法

class Solution {
     public int singleNumber(int[] nums) {
            Arrays.sort(nums);
            int num = 1;
            for (int i = 1; i < nums.length; i++) {
              if (nums[i] == nums[i - 1]){
                  num++;
              }else {
                  if (num == 1)
                      return nums[i - 1];
                  num = 1;
              }
            }
            return nums[nums.length - 1];
        }
}

方法二:hash

class Solution {
    public int singleNumber(int[] nums) {
        Map freq = new HashMap();
        for (int num : nums) {
            freq.put(num, freq.getOrDefault(num, 0) + 1);
        }
        int ans = 0;
        for (Map.Entry entry : freq.entrySet()) {
            int num = entry.getKey(), occ = entry.getValue();
            if (occ == 1) {
                ans = num;
                break;
            }
        }
        return ans;
    }
}

方法三:依次确定每一个二进制位

class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for (int i = 0; i < 32; ++i) {
            int total = 0;
            for (int num: nums) {
                total += ((num >> i) & 1);
            }
            //余数就是出现一次的那个数的该位的二进制
            if (total % 3 != 0) {
                ans |= (1 << i);
            }
        }
        return ans;
    }
}

4.只出现一次的数字 III( LeetCode 260 )

方法一:hash

class Solution {
      public int[] singleNumber(int[] nums) {
            int[] ans = new int[2];
            int k = 0;
            Map map = new HashMap<>();
            for (int x:nums
                 ) {
                map.put(x,map.getOrDefault(x,0) + 1);
            }
            for (Map.Entry x:map.entrySet()
                 ) {
                Integer key = x.getKey();
                Integer value = x.getValue();
                if (value == 1){
                    ans[k++] = key;
                }
            }
            return ans;
        }
}

方法二:
位运算

class Solution {
        
        public int[] singleNumber(int[] nums) {
            int xorsum = 0;
            for (int num : nums) {
                xorsum ^= num;
            }
            //Integer.MIN_VALUE = 10000000000000000000000000000000
            // 防止溢出
            int lsb = (xorsum == Integer.MIN_VALUE ? xorsum : xorsum & (-xorsum));
            int type1 = 0, type2 = 0;
            for (int num : nums) {
                if ((num & lsb) != 0) {
                    type1 ^= num;
                } else {
                    type2 ^= num;
                }
            }
            return new int[]{type1, type2};
        }
    }
5.最大单词长度乘积( LeetCode 318 )

方法一:暴力解法 超时
时间复杂度 O(n3)

  class Solution {
        public int maxProduct(String[] words) {
            int max = 0;
            for (int i = 0; i < words.length - 1; i++) {
                for (int j = i + 1; j < words.length; j++) {
                    max = Math.max(max,mulStr(words[i],words[j]));
                }
            }
            return max;
        }
        public int mulStr(String s,String s2){
            Set set = new HashSet<>();
            for (char x:s.toCharArray()
                 ) {
                set.add(x);
            }
            for (char x:s2.toCharArray()
                 ) {
                if (set.contains(x))return 0;
            }
            return s.length() * s2.length();
        }
    }

方法二:位运算
方法一的基础上进行优化
降低比较a,b是否包含相同字符的时间复杂度

   class Solution {
        public int maxProduct(String[] words) {
            int[] temp = new int[words.length];
            for (int i = 0; i < words.length; i++) {
                int x = 0;
                //遍历words[i]
                //x的二进制表示中
                //第0位为1表示word[i]中存在a
                //第1位为1表示word[i]中存在b
                //...
                for (int j = 0; j < words[i].length(); j++) {
                    x = x | (1 << (words[i].charAt(j) - 'a'));
                }
                temp[i] = x;
            }
            int ans = 0;
            for (int i = 0; i < words.length - 1; i++) {
                for (int j = i + 1; j < words.length; j++) {
                    if ((temp[i] & temp[j]) == 0){
                        ans = Math.max(ans,words[i].length() * words[j].length());
                    }
                }
            }
            return ans;
        }
    }

方法三:对方法二进行优化

class Solution {
    public int maxProduct(String[] words) {
        Map map = new HashMap();
        int length = words.length;
        for (int i = 0; i < length; i++) {
            int mask = 0;
            String word = words[i];
            int wordLength = word.length();
            for (int j = 0; j < wordLength; j++) {
                mask |= 1 << (word.charAt(j) - 'a');
            }
            if (wordLength > map.getOrDefault(mask, 0)) {
                map.put(mask, wordLength);
            }
        }
        int maxProd = 0;
        Set maskSet = map.keySet();
        for (int mask1 : maskSet) {
            int wordLength1 = map.get(mask1);
            for (int mask2 : maskSet) {
                if ((mask1 & mask2) == 0) {
                    int wordLength2 = map.get(mask2);
                    maxProd = Math.max(maxProd, wordLength1 * wordLength2);
                }
            }
        }
        return maxProd;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/965950.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号