题目
剑指 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;
}
}
未完待续!