转自:http://www.mitbbs.com/article_t/JobHunting/32604553.html
Given a list of words, find two strings S & T such that:
a. S & T have no common characterb. S.length() * T.length() is maximized
没想到什么比O(n^2)好的方法,毕竟是partially order, 不是total order
但到不了O(n^2*l), 只是O(n^2 + nl).只需要过一遍string计算sign就可以了,另外将
数组按长度从大到小排列,提前剪枝也可以优化一些,但复杂度还是O(n^2)
const int INT_BITS = sizeof(int) * 8;
const int DATA_LEN = 256/INT_BITS;
class Int256 {
vector<int> data;
public:
Int256(): data(DATA_LEN, 0) {
}
Int256(string s): data(DATA_LEN, 0) {
for (auto c: s) {
Set((unsigned char)c);
}
}
void Set(int l) {
data[l/INT_BITS] |= 1 << (l%INT_BITS);
}
bool IsZero() const {
for (int i = 0; i < DATA_LEN; ++i) {
if (data[i]) return false;
}
return true;
}
Int256 BitAnd(const Int256& rhs) {
Int256 results;
for (int i = 0; i < DATA_LEN; ++i) {
results.data[i] = data[i] & rhs.data[i];
}
return results;
}
bool operator==(const Int256& rhs) {
for (int i = 0; i < DATA_LEN; ++i) {
if (data[i] != rhs.data[i]) return false;
}
return true;
}
};
struct Node {
string s;
Int256 sign;
Node(string s1):s(s1), sign(s1){};
};
bool CompareNodes(const Node& lhs, const Node& rhs) {
return lhs.s.size() > rhs.s.size();
}
int NoOverlapMultply(vector<string> ss) {
vector<Node> nodes;
for (string s: ss) {
nodes.push_back(Node(s));
}
sort(nodes.begin(), nodes.end(), CompareNodes);
int curMax = 0;
for (int i = 0; i < nodes.size(); ++i) {
int iLen = nodes[i].s.size();
Int256 iSign = nodes[i].sign;
for (int j = i + 1; j < nodes.size(); ++j) {
if (nodes[j].s.size() * iLen <= curMax) break;
Int256 andSign = iSign.BitAnd(nodes[j].sign);
if (andSign.IsZero()) {
curMax = nodes[j].s.size() * iLen;
break;
}
}
}
return curMax;
}