【力扣刷题笔记】整数-只出现一次的数字

题目

剑指 Offer II 004.只出现一次的数字

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素

分析

本题主要是考虑到一个数,是在int范围内,那么这个数就不会超过32位,可以用一个32位的数组去表示一个数的每一位(换成2进制看)。
推广:并且考虑到一个数,出现m次,那么第i位的数之和,一定可以被m整除。
即出现m次的数字的第i数位之和 % m 一定为 0

class Solution {
    public int singleNumber(int[] nums) {
        //一个数的长度不会超过32位
        //所以可以用一个32位的数组,表示一个数第i位的数
        int[] bitSums = new int[32];
        for(int num: nums) {
            for(int i = 0; i < 32; i++) {
                bitSums[i] += (num >> (31 - i) & 1); //左数第i位,移动到最右边
            }//通过右移位(会自动变成2进制位串操作),
        }//累加每个第i位的数的和,

        int res = 0;
        //异或操作, 出现3次,那么第i位的和,一定能够被3整除,这点可以推广
        for(int i = 0; i < 32; i++) {
            res = (res << 1) + bitSums[i] % 3;
        }// 从一个2进制还原到10进制,左移(*2) + 每位的数(%3)
        return res;
    }
}

题目

剑指 Offer II 005. 单词长度的最大乘积

给定一个字符串数组 words,请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/aseY1I
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

方法一

因为总共只有26个小写字母,所以可以用一个

class Solution {
    public int maxProduct(String[] words) {
        int[] flags = new int[words.length];
        for(int i = 0; i < words.length; i++) {
            for(char ch: words[i].toCharArray()) {
                flags[i] = flags[i] | (1 << (ch - 'a')); //26个字母长度,int32位可以用位串表示某个是否存在
            }
        }
        
        int maxLen = 0;
        for(int i = 0; i < words.length; i++) {
            int len1 = words[i].length();
            for(int j = i + 1; j < words.length; j++) {
                if((flags[i] & flags[j]) == 0) {
                    
                    int len2 = words[j].length();
                    maxLen = Math.max(maxLen, len1 * len2);
                }
            }
        }
        return maxLen;
    }
}

未完待续!

你可能感兴趣的:(leetcode,算法,职场和发展)