程序员面试金典——18.10字符串变换

程序员面试金典——18.10字符串变换

Solution1:

我的答案。穷举法,个人认为此题还是有点难度的。。。
利用了倒推法以及很高的时间复杂度才解决,并不值得推崇呀。

class Change {
public:
    int countChanges(vector<string> dic, int n, string s, string t) {
        // write code here
        if(n <= 1 || s.size() != t.size())
            return -1;
        int nums_diff = 0, count_step = 0;
        vector<bool> symbol(dic.size(), false);//未访问:false;访问过:true
        vector<string> candi = {t}; //把备胎集初始化为目标string
        for(count_step = 1; ; count_step++) {
            int old_size = candi.size(); //保存上一次的size
            add_1_diff(dic, symbol, candi);
            if(find(candi.begin(), candi.end(), s) != candi.end())
                return count_step;
            if(candi.size() == old_size)
                return -1;
        }
        return -1;
    }
    //找出两子字符串不同的位
    vector<int> count_diff_char(string &s1, string &s2) {
        vector<int> res;
        for (int i = 0; i <= s1.size(); i++) 
            if (s1[i] != s2[i])
                res.push_back(i);
        return res;
    }

    void add_1_diff(vector<string> &dic, vector<bool> &symbol, vector<string> &candi) {
        int candi_size = candi.size();
        for(int i = 0; i < candi_size; i++) {
            for(int j = 0; j < dic.size(); j++) {
                if(symbol[j] == false) {
                    if(count_diff_char(candi[i], dic[j]).size() == 1) {
                        candi.push_back(dic[j]);
                        symbol[j] = true;
                    }
                }
            }
        }
        return;
    }
};

vector、map 判断某元素是否存在、查找指定元素

参考网址:https://www.cnblogs.com/SZxiaochun/p/7131361.html

一、vector

    1.判断某元素是否存在
        vector<string> vStr;
        int nRet = std::count(vStr.begin(), vStr.end(), "xiaochun");//判断vector中是否有 "xiaochun" 这个元素

    2.查找某个元素

        方法一:

          自己写循环遍历


        方法二:

          vector<string> vec;
          vector<string>::iterator iter;
          string gpcode="SZ000001";
          iter = find(vec.begin(), vec.end(), gpcode);
          if(iter != vec.end()) {
            //vec中存在"SZ000001"
          }
          else {
            //没找到
          }         
        注意:
      
        如果vector中保存的是自定义类型(结构体/类),则需要为该类型重载==操作符。再用find

        #include <stdio.h>
        #include <vector>
        #include <string>
        #include <algorithm>  //是C++的标准模版库(STL)中最重要的头文件之一,提供了大量基于迭代器的非成员模板函数。
        class DemoStruct {
          public:
          string gpcode;
          int ymd;
          vector<int> vec;
          DemoStruct() {
            ymd = 20170707;
            gpcode = "";
          }
          bool operator == (const DemoStruct & obj) const //重载 “==” 操作符,函数最后的 const 别忘了,否则会报错。(详见:http://www.cnblogs.com/SZxiaochun/p/7731900.html) {
            return ymd == obj.ymd && gpcode == obj.gpcode;  //具体匹配条件,可以自己设定
          }
        };

        int main() {  
          vector<DemoStruct> vec_struct;
          DemoStruct demo;
          demo.gpcode = "SZ000001";
          demo.ymd = 20170707;
          demo.vec.push_back(0);
          vec_struct.push_back(demo);

          DemoStruct tmpdemo;
          tmpdemo.gpcode = "SZ000001";
          tmpdemo.ymd = 20170707;

          vector<DemoStruct>::iterator iter;
          iter = find(vec_struct.begin(), vec_struct.end(), tmpdemo);
          if (iter != vec_struct.end()) {
            printf("%s","find it");
          }
          return 0;
        }

二、map

    1.判断某元素是否存在
        map<int, string> mapDemo;        
        bool bRet = mapDemo.count(100);//判断mapDemo中是否有 key = 100 的元素

    2.查找某个元素
        map<int, string>::iterator iter = mapDemo.find(100);
        if (iter != m_Int.end()) {
            //找到了
        }
        else {
            //没找到
        }

Solution2:

参考网址:https://www.nowcoder.com/profile/9076570/codeBookDetail?submissionId=12491921
思路:
最短搜索路径,所以是广度优先搜索(BFS)。
按照定义,存在一个字母差异的单词为邻居,因此采用逐位替换字母并查找字典的方法寻找邻居。
对队列中的每个单词记录路径长度。 queue<pair<string,int>>q q u e u e < p a i r < s t r i n g , i n t >> q ; 从start进入队列记作1.长度为i的字母的邻居,如果没有访问过,则路径长度为i+1.
也很复杂呀~
代码:

class Change {
public:
    int countChanges(vector<string> dic, int n, string s, string t) {
        vector<string>::iterator ite = find(dic.begin(), dic.end(), s);
        int result = BFS(s, t, dic);
        if(ite != dic.end()) {
            --result;
        }//if
        return result;
    }
private:
    int BFS(string start, string end, vector<string> &dict) {
        if(start == end) {
            return 0;
        }//if
        // 存放单词和单词所在层次
        queue<pair<string, int> > q;
        q.push(make_pair(start, 1));
        // 判断是否访问过
        vector<string> visited;
        visited.push_back(start);
        while(!q.empty()) {
            pair<string, int> cur = q.front();
            q.pop();
            string word = cur.first;
            int size = word.size();
            // 穷尽所有可能的变换
            for(int i = 0; i < size; ++i) {
                string newWord(word);
                // 每次只变换一个字符 有26种可能
                for(int j = 0; j < 26; ++j) {
                    newWord[i] = 'a' + j;
                    // 找到目标返回
                    if(newWord == end) {
                        return cur.second + 1;
                    }//if
                    // 判断之前访问过或者是否在字典里
                    vector<string>::iterator ite = find(dict.begin(), dict.end(), newWord);
                    vector<string>::iterator ite2 = find(visited.begin(), visited.end(), newWord);
                    if(ite2 == visited.end() && ite != dict.end()) {
                        visited.push_back(newWord);
                        q.push(make_pair(newWord,cur.second + 1));
                    }//if
                }//for
            }//for
        }//while
        return -1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值