由所给长度相同的单词,按位组合出字典序最小的新单词

一道笔试编程题,想出一个时空复杂度O(N*L)的方法,不知道有没有更快的 。

题目描述:现给出N个长度为L的单词。单词中仅包含大写英文字母(A-Z)。

1<=N<=2000

1<=L<=10

你可以从这些单词中的第n个字母中挑一个作为你拼词的第n个字母

比如给出N=3个L=4的单词:

CAKE

TORN

SHOW

你可以(但不仅限于)拼出以下单词:

CORN

SAKE

CHRE

但不能拼出:

KARE

因为N个单词中,没有首字母为K的。

问:按照上述规则,拼出一个与这N个单词都不相同的新单词。若无法拼出,则输出“-”。若有超过一个符合条件的单词,则输出字典序最小的那个单词。

输入描述:第一行包含2个正整数N、L,分别表示单词数量与每个单词长度。
接下来有N行,每行包含一个长度为L的字符串,字符串中仅包含大与英文字母。

这N个字符串表示给出的N个单词
输出描述:
输出占一行,仅包含一个字符串,表示题目要求的单词,若找不到这样的单词,则按题目表述出“-”。

#include 
#include 
#include 
#include 
using namespace std;
void moveNext(const vector&build, char ¤t) {//O(1)
    current++;
    while (current-'A' < build.size() 
        && build[current-'A'] == false) {
        current++;
    }
}
int englishWord() {
    int N, L;
    while (cin >> N >> L) {
        unordered_set words;
        for (int i = 0; i < N; ++i) {//O(N),保存N个长度为L的字符串
            string w;
            cin >> w;
            words.emplace(std::move(w));
        }
//保存每个位置出现过的字母,这样可以锁定为26,且不用考虑排序,用std::set也可以
        vector> exist(L, vector(26, false));
        vector firstKey(L,'Z'+1);//保存每个位置出现的字典序最小的字母
        for (auto& s : words) {//时间复杂度O(N*L)
            for (int i = 0; i < L; ++i) {
                exist[i][s[i] - 'A'] = true;
                if (s[i]< firstKey[i])
                    firstKey[i] = s[i];
            }
        }
        string res(L, '\0');
        for (int i = 0; i < L; ++i) {//O(L),生成第一个答案
            res[i] = firstKey[i];
        }
        //检查是否重复,并且自加、进位
        while (words.find(res) != words.end()) {//O(L)
            int pos = L - 1;
            moveNext(exist[pos], res[pos]);//从最后一位开始自加
            while (pos > 0 && res[pos] == 'Z' + 1) {//逐位判断是否需要进位
                res[pos] = firstKey[pos];
                moveNext(exist[pos - 1], res[pos - 1]);
                pos--;
            }
            if (pos == 0 && res[pos] == 'Z' + 1) {//找完了,全都不符合
                res = "-";
                break;
            }
        }
        cout << res;
    }
    return 0;
}

题给测试用例


3 4
COKE
TARN
SHOW


输出CAKE,通过

自己的例子


3 5

AAAAA

AAAAB

AAAAC


输出-,通过


5 5
AAAAA
AAAAB
AAAAC
ABCDE
BBBBF


输出AAAAE,通过


7 5
AAAAA
AAAAB
AAAAC
AAABA
AAABB
AAABC
AABAA


输出AABAB,通过


9 3
AAA
AAB
AAC
ABA
ABB
ABC
ACA
ACB
ACC 


输出-,通过 

 

欢迎打脸

你可能感兴趣的:(算法)