力扣318. 最大单词长度乘积

第一百天 --- 力扣318. 最大单词长度乘积

题目一

力扣:318. 最大单词长度乘积

在这里插入图片描述

在这里插入图片描述

思路

我们需要在一个一维数组中找到任意两个目标串,进行长度乘积,避免不了是O(N^2)的寻找,我们能做的是,在每次进行比较的时候,保证O(1)内求出答案,并且对搜素过程进行剪枝,比如将之缩减比较次数,或者用一些比如贪心的思想减少比较次数。

模拟法(暴力解法)

直接模拟题意,每次比较先把一个字符串存进set中,遍历另一个串,看有没有重复字符。

二:位运算法

1、根据题目中数据约定,每个字符串最多由26个字母所组成。
2、在两个二进制数中,对应位是不是都为1,用&操作判断。
3、看题意,有用的两个字符串是两个串中没有重复出现的字符,也就是说得去找两个串中出现的字符,关注点在于每个字符出现or没出现,很明显就两个状态,0,1即可表示,所以用位运算即可。一旦一样的字符出现了,对应位置两个1,反之一个1,一个0或者都是零,用&操作就能分得开。
4、所以,再由一共26中字符这个条件,我们就可以得到算法:准备一个长度为26(二进制)的int正数(int最大31位,不越界),从0-25位分别表示a-z,默认都是0,哪位出现了为1,这样就把字符串转换成了一个二进制数,如果没有重复出现的字符,二者按位&结果一定是0.

代码

class Solution {
public:
	int maxProduct(vector<string>& words) {
		int ans = 0;
		unordered_set<char> item;
		for (int i = 0; i < words.size(); i++) {
			for (int k = 0; k < words[i].size(); k++) {
				item.insert(words[i][k]);//存第一个字符串出现的字符
			}
			for (int j = i + 1; j < words.size(); j++) {
				bool flag = false;
				for (int k = 0; k < words[j].size(); k++) {
					if (item.count(words[j][k]) > 0) {//按位比较
						flag = true;
						break;
					}
				}
				if (flag) {
					continue;
				}
				else {
					int tmp = words[i].size()*words[j].size();
					ans = max(ans, tmp);
				}
			}
			item.clear();//需要进行清理,把上一个串的信息清了。
		}
		return ans;
	}
};

所有代码均以通过力扣测试
(经过多次测试最短时间为):

在这里插入图片描述

class Solution {
public:
	int maxProduct(vector<string>& words) {//本题的矛盾点在于怎么在O(1)内看出二者也没有相同的字符
		//也就是说得去找两个串中出现的字符,关注点在于每个字符出现or没出现,很明显就两个状态,0,1即可表示
		//一旦一样的字符出现了,对应位置两个1,反之一个1,一个0或者都是零,用&操作就能分得开。
		int ans = 0;
		vector<int> marks(words.size(), 0);//存预处理结果
		for (int i = 0; i < words.size(); i++) {//将字符串进行一个预处理,转化成一个十进制数
			int tar = 0;
			for (char c : words[i]) {
				int k = c - 'a';//对应的第几位
				tar |= (1 << k);//并入tar中
			}
			marks[i] = tar;
		}
		for (int i = 0; i < words.size(); i++) {
			for (int j = i + 1; j < words.size(); j++) {
				if ((marks[i] & marks[j]) == 0) {//这里一定加好括号!!!!!!!
					int tmp = words[i].size()*words[j].size();
					ans = max(ans, tmp);
				}
			}
		}
		return ans;
	}
};


所有代码均以通过力扣测试
(经过多次测试最短时间为):
在这里插入图片描述
在这里插入图片描述

其实位运算的算法还有进步空间,因为正如我上面说的,在查找任何两个字符串方面上,有很大进步空间,同样的十进制数,我们这里用贪心的想法进行优化:mark值一样,我要求的是长度之积最大,所以各个分量也要尽可能大,所以mark一样留下长度大的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JLU_LYM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值