LeetCode Word Ladder II(双向广搜)

10 篇文章 0 订阅
2 篇文章 0 订阅

双向广搜字符串最短距离最短


#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<sstream>
#include<string>
#include<bitset>
#include<utility>
#include<numeric>

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;

const LL LINF = (1LL <<62);
const int INF = 1 << 30;

const int NS = 500010;
const int MS = 19;
const int MOD = 1000000007;
const double PI = acos(-1.0);

#define form(_i, L, R) for (int (_i) = L; (i) <= (R); ++(_i))

inline bool isdigit(char ch){return ((ch<='9')and(ch>='0'));}
inline void read(int &x){
    char ch;
    bool flag=false;
    for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') flag=true;
    for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    x=flag?-x:x;
}

#ifndef ONLINE_JUDGE
    typedef set<string> StringSet;
#endif
#ifdef ONLINE_JUDGE
    typedef unordered_set<string> StringSet;
#endif
struct Node;
typedef bool (*NodeCmper) (Node*, Node*);
typedef set<Node *, NodeCmper> NodeSet;
typedef vector<string> VString;

struct Node{
    string word;
    vector<Node *> parents;
    Node(){}
    Node(string _word){
        word = _word;
        parents.clear();
    }

    bool operator < (const Node& cmp){
        return ((this->word) < (cmp.word));
    }

    void addParents(Node *cur)
    {
        parents.push_back(cur);
    }

    vector<VString *>* getPath()
    {
        vector<VString *> *paths = new vector<VString *>;
        if(!parents.empty())
        {
            vector<VString *> *pre;
            for(__typeof(parents.begin()) it = parents.begin(); it != parents.end(); it++)
            {
                pre = (*it)->getPath();
                for(__typeof(pre->begin()) itr = pre->begin(); itr != pre->end(); itr++)
                {
                    (*itr)->push_back(word);
                }
                paths->insert(paths->end(), pre->begin(), pre->end());
            }
        }
        else
        {
            VString *cur = new VString(1, word);
            paths->push_back(cur);
        }
        return (paths);
    }

    void findNext(NodeSet *nexts, NodeSet *tail, vector<VString>& ans, bool isLeft, StringSet &words)
    {
        string cur = word;
        int len = cur.length();
        for(int i = 0; i < len; i++)
        {
            char reChar = cur[i];
            for(char ch = 'a'; ch <= 'z'; ch++)
            {
                if(ch == reChar) continue;
                cur[i] = ch;
                if(words.find(cur) != words.end())
                {
                    Node* next = new Node(cur);
                    checkMatch(next, nexts, tail, ans, isLeft);
                }
            }
            cur[i] = reChar;
        }
        return ;
    }

    void checkMatch(Node* next, NodeSet *nexts, NodeSet *tail, vector<VString>& ans, bool isLeft)
    {
        __typeof(tail->begin()) it = tail->find(next);
        if(it != tail->end())
        {
            vector<VString *> *tPath, *hPath;
            hPath = this->getPath();
            tPath = (*it)->getPath();
            if(!isLeft) swap(hPath, tPath);

            __typeof(hPath->begin()) pH, pT;
            for(pH = hPath->begin(); pH != hPath->end(); pH++)
            {
                for(pT = tPath->begin(); pT != tPath->end(); pT++)
                {
                    ans.push_back(*(*pH));
                    ans.back().insert(ans.back().end(), (*pT)->rbegin(), (*pT)->rend());
                }
            }
        }
        else if(ans.empty())
        {
            __typeof(nexts->begin()) itr = nexts->find(next);
            if(itr != nexts->end())
            {
                (*itr)->addParents(this);
            }
            else
            {
                next->addParents(this);
                nexts->insert(next);
            }
        }
    }
};

bool nodeCmp(Node* pa, Node* pb)
{
    return pa->word < pb->word;
}

class Solution {
public:
    vector<VString> findLadders(string begins, string ends, StringSet &words) {
        vector<VString> ans;
        if(begins == ends)
        {
            ans.push_back(VString(2, begins));
        }
        words.insert(ends);//防止begins可以一次转换到ends的情况
        Node pHead = Node(begins), pTail = Node(ends);
        NodeSet *head = new NodeSet(nodeCmp), *tail = new NodeSet(nodeCmp), *nexts = new NodeSet(nodeCmp);
        head->insert(&pHead), tail->insert(&pTail);
        bool isLeft = true;
        int circle = 0;
        while(ans.empty() && head->size() && tail->size())
        {
            circle++;
            if( head->size() > tail->size() )
            {
                swap(head, tail);
                isLeft = !isLeft;
            }
            nexts->clear();
            for(__typeof(head->begin()) it = head->begin(); it != head->end(); it++)
            {
                words.erase((*it)->word);
            }
            for(__typeof(head->begin()) it = head->begin(); it != head->end(); it++)
            {
                (*it)->findNext(nexts, tail, ans, isLeft, words);
            }
            swap(head, nexts);
        }
        return ans;
    }
};

char s[101010];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("ladderLength.in", "r", stdin);
    freopen("ladderLength2.out", "w", stdout);
#endif
    set<string> words;
    string bW, eW, wo;
    cin>>bW>>eW;
    bW = bW.substr(1, bW.size() - 2);
    eW = eW.substr(1, eW.size() - 2);
    scanf("%s", s);
    cout<<"bW = "<<bW<<" eW = "<<eW<<endl;//<<wo<<endl;
    const char *d = ",[]\"";
    char *p;
    p = strtok(s,d);
    int cnt = 0;
    while(p)
    {
        printf("%s\n",p);
        words.insert(string(p));
        if(cnt > 5000)
        {
            break;
        }
        p=strtok(NULL,d);
        cnt++;
    }
    printf("words.size = %d\n", (int)words.size());
    Solution sol;
    vector<VString> ans = sol.findLadders(bW, eW, words);

    printf("cnt = %d ans = %d\n", cnt, ans.size());
    int sz = ans.size();
    for(int i = 0; i < sz; i++)
    {
        VString cur = ans[i];
        int len = cur.size();
        for(int j = 0; j < len; j++)
        {
            cout<<cur[j]<<"->";
        }
        cout<<"NULL"<<endl;
    }
    return 0;
}

//   __typeof(val.begin()) it = val.begin();
//ios::sync_with_stdio(false);cout<<setprecision(30);


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值