目录
传送门
课后习题
318.最大单词长度乘积
318. 最大单词长度乘积https://leetcode-cn.com/problems/maximum-product-of-word-lengths/
题目描述:
给定一个字符串数组
words
,找到length(word[i]) * length(word[j])
的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0
int maxProduct(char ** words, int wordsSize){
/*
因为 int 32位,而字母就26个,所以用一个int可以表示一个字符串中所有出现的字母
*/
int *hash = (int*)malloc(sizeof(int)*wordsSize);
int i,j,ans = 0;
for(i=0; i<wordsSize; ++i){
int len = strlen(words[i]);
hash[i] = 0;
for(j=0; j<len; ++j){
hash[i] |= 1<<(words[i][j]-'a'); //出现就将对应的位 置1
}
}
for(i=0; i<wordsSize; ++i){
for(j=i+1; j<wordsSize; ++j)
if((hash[i] & hash[j]) == 0){ //如果 & 为0,则说明没有同时为 1 的位,即没有公共字母
int t = strlen(words[i]) * strlen(words[j]);
printf("%d",t);
if(t > ans)
ans = t;
}
}
return ans;
}
1318.或运算的最小翻转次数
1318. 或运算的最小翻转次数https://leetcode-cn.com/problems/minimum-flips-to-make-a-or-b-equal-to-c/
题目描述:
给你三个正整数 a、b 和 c。
你可以对 a 和 b 的二进制表示进行位翻转操作,返回能够使按位或运算 a OR b == c 成立的最小翻转次数。
「位翻转操作」是指将一个数的二进制表示任何单个位上的 1 变成 0 或者 0 变成 1 。
int GetBit(int x,int i){
return (x>>i) & 1; //取x第 i 位
}
int minFlips(int a, int b, int c){
int i,ans = 0;
for(i=0;i<31;++i){
int ai = GetBit(a,i);
int bi = GetBit(b,i);
int ci = GetBit(c,i);
if((ai | bi) == ci) //如果相等 则无需翻转
continue;
if(ci == 0) // 如果目标位0 则需要将a、b都置0
ans += ai+bi;
else if(ci == 1) // 只需要其中一个置 1就行了
ans += 1;
}
return ans;
}
898.子数组按位或操作
898. 子数组按位或操作https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/
题目描述:
我们有一个非负整数数组 A。
对于每个(连续的)子数组 B = [A[i], A[i+1], ..., A[j]] ( i <= j),我们对 B 中的每个元素进行按位或操作,获得结果 A[i] | A[i+1] | ... | A[j]。
返回可能结果的数量。 (多次出现的结果在最终答案中仅计算一次。)
//看到数据范围10^9,那得开多大空间,直接换c++做了
class Solution {
public:
int subarrayBitwiseORs(vector<int>& arr) {
unordered_set<int> st;
int Max=0;
for(int i:arr){
Max |= i; //求出最大值
}
for(int i=0;i<arr.size();++i){
int num = arr[i];
st.insert(num);
for(int j=i+1;j<arr.size();++j){
num |= arr[j];
st.insert(num);
if(num == Max) //如果已经达到最大值,再或下去也不会有新的结果 直接退出
break; //没有这个会超时,我试了
}
}
return st.size();
}
};
每天打卡打卡打卡!!!