[程序员面试金典]1001.字符串变换

简介:

题目描述

现有一个字典,同时给定字典中的两个字符串s和t,给定一个变换,每次可以改变字符串中的任意一个字符,请设计一个算法,计算由s变换到t所需的最少步数,同时需要满足在变换过程中的每个串都是字典中的串。
给定一个string数组dic,同时给定数组大小n,串s和串t,请返回由s到t变换所需的最少步数。若无法变换到t则返回-1。保证字符串长度均小于等于10,且字典中字符串数量小于等于500。
测试样例:
[“abc”,”adc”,”bdc”,”aaa”],3,”abc”,”bdc”
返回:2

思路

最短搜索路径,所以是广度优先搜索(BFS)。
按照定义,存在一个字母差异的单词为邻居,因此采用逐位替换字母并查找字典的方法寻找邻居。
对队列中的每个单词记录路径长度。queue

/*---------------------------------------
*   日期:2015-08-11
*   作者:SJF0115
*   题目:1001.字符串变换
*   来源:程序员面试金典
*   网址:http://www.nowcoder.com/practice/4818ae796bbc4a85a8cdd8e155c06d46?rp=4&ru=/ta/cracking-the-coding-interview
-----------------------------------------*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <queue>
using namespace std;

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;
    }
};

int main() {
    Change s;
    //vector<string> set = {"vvz","bbaa","f","bbba","bbaa","baoa","btoa","bbba","dcki","bbbb","ge","atoj","baaa","btoj","ae"};
    vector<string> set = {"abc","adc","bdc","aaa"};
    string start("abc");
    string end("bdc");
    int result = s.countChanges(set,5,start,end);
    // 输出
    cout<<result<<endl;
    return 0;
}
目录
相关文章
|
1月前
|
存储
力扣面试经典题之数组/字符串
力扣面试经典题之数组/字符串
23 0
|
3月前
|
存储 算法 程序员
【Leetcode 程序员面试金典 01.01】判定字符是否唯一 —— 位运算|哈希表
可以使用哈希表或位运算来解决此问题:由题可知s[i]仅包含小写字母,int[26]即能表示字符的出现次数;
|
3月前
|
算法 程序员 索引
【Leetcode 程序员面试金典 02.08】 —— 环路检测 |双指针
我们可以使用双指针解决本题,由数学推导可知:a 的距离为(环长度的倍数 - b),即 tmp 指针从头节点走到环开头节点等于 slow 指针走到环开头节点的距离
|
3月前
|
Java 程序员
【Leetcode 程序员面试金典 05.01】插入 —— 位运算
位运算问题,只需要把 N 的 i 到 j 位都置 0 后再和 M 左移 i 位的结果进行按位或即可
|
3月前
|
算法 架构师 安全
10年Java面试总结:Java程序员面试必备的面试技巧
作为一名资深10年Java技术专家,我参与了无数次的面试,无论是作为面试者还是面试官。在这里,我将分享我的一些面试经历和面试技巧,希望能帮助即将面临面试的Java程序员们。回顾我的Java职业生涯,我清晰地记得一次特别的面试经历。那是我申请一家知名科技公司的Java开发岗位。为了这次面试,我花了几周的时间准备,这不仅包括Java的基础和高级知识,还有关于公司产品的研究。
146 0
|
1月前
|
算法 测试技术 索引
力扣面试经典题之数组/字符串(二)
力扣面试经典题之数组/字符串(二)
13 0
|
2月前
|
运维 算法 程序员
程序员去国企:长城资产IT岗位秋招面试记录
【2月更文挑战第7天】本文介绍2024届秋招中,中国长城资产管理股份有限公司的信息技术岗岗位一面的面试基本情况、提问问题等~
|
3月前
|
算法 Java C++
数据结构与算法面试题:给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。(提示:使用动态规划或者中心扩散)
数据结构与算法面试题:给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。(提示:使用动态规划或者中心扩散)
41 0
|
27天前
|
Java 程序员
java线程池讲解面试
java线程池讲解面试
50 1
|
2月前
|
存储 关系型数据库 MySQL
2024年Java秋招面试必看的 | MySQL调优面试题
随着系统用户量的不断增加,MySQL 索引的重要性不言而喻,对于后端工程师,只有在了解索引及其优化的规则,并应用于实际工作中后,才能不断的提升系统性能,开发出高性能、高并发和高可用的系统。 今天小编首先会跟大家分享一下MySQL 索引中的各种概念,然后介绍优化索引的若干条规则,最后利用这些规则,针对面试中常考的知识点,做详细的实例分析。
248 0
2024年Java秋招面试必看的 | MySQL调优面试题