暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

数据结构和算法【81】单词接龙(华为OD笔试题目)

皮皮克克 2023-11-18
117

点击关注公众号,干货第一时间送达


这题是一道华为OD笔试题目,

具体什么时间点考的,

小编不确定哈

小编不是面试官,也不是出题人,

只是个解题人哈

抛开诸位对华为OD的看法,

只看此题,

你能解答出来吗?


在力扣上可以找到原题:

https://leetcode.cn/problems/word-ladder/solutions/276923/yan-du-you-xian-bian-li-shuang-xiang-yan-du-you-2/



一、屏幕前的吴彦祖和刘亦菲们,请听题

举个例子:


题意都明白否?

其实就是个最短转换路径问题,

也就是图问题。

最短转换路径问题的解法有哪些?

广度优先遍历 & 深度优先遍历


二、解题

(插句题外话哈,互联网企业的笔试题目,图的问题基本是必考的。三道笔试题,至少有一题是图相关的,所以诸君平时多练练这些题目哈,有备无患)

明确了是图,咱们先在草稿纸上画个简单的图:

接下来就是求解,

beginWord -> endWord 的最短路径了。

题目中设定的是每个单词中的每个字符可以替换一次,

也就是说:

如上图,单词hit的每个字符都要尝试 a-z 的单个替换。

当然,需要判断替换形成的新字符串,是否在给定的 wordList 中,即是有效的:

如果有效,则路径+1,

最终新字符串正好等于 endWord 即可。


因为这个图是无向,为了防止回头,走过的路我们记录下来,

就是新的单词都记录下来,下次不再记录了:

聪明的小伙伴肯定发现了,

这题的的最短路径求解,

就是 dijstra 算法

看了这么多讲解,

最重要的还是要code,

看看代码。



完整代码:

public class CodingDemo_03 {

    /**
     * 单词接龙
     * @param beginWord
     * @param endWord
     * @param wordList
     * @return
     */

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        //1,将给定单词列表转换为set,方便后续查找
        Set<String> wordSet = new HashSet<>(wordList);

        //因为题目要求 beginword 不在给定单词列表,这里我们删除可能存在的情况
        wordSet.remove(beginWord);

        //如果给定单词列表不包含 endword,肯定无法转换
        if (!wordSet.contains(endWord)){
            return 0;
        }

        //2,采用广度优先遍历,判断哪些可以满足一个字符替换
        //并同时记录哪些单词被访问过
        Deque<String> queue = new LinkedList<>();
        queue.addLast(beginWord);
        Set<String> visited = new HashSet<>();


        //开始遍历
        int step = 1//记录转换次数
        while (!queue.isEmpty()){
            int curSize = queue.size();

            //广度遍历
            for (int i = 0; i < curSize; i++) {
                //弹出当前单词
                String curWord = queue.pollFirst();
                //判断当前单词,是否可以只变化一个字符,即可转换为 endWord
                //如果可以,则直接返回记录步数 step
                if (changeOneWordToEnd(wordSet, queue, visited,endWord, curWord)){
                    return step + 1;
                }
            }

            step++;//转换步数增加
        }
        return 0;
    }


    private boolean changeOneWordToEnd(Set<String> wordSet, Deque<String> queue,
                                       Set<String> visited, String endWord, String curWord)
{
        //1,因为要判断当前单词curWord,
        //只变化一个字符
        //所以先将字符串转换字符数组,方便字符替换
        final char[] ch = curWord.toCharArray();

        //2,尝试对每个字符进行 a-z 替换
        for (int i = 0; i < ch.length; i++) {
            //2.1 先把老字符记录下来
            char odd = ch[i];

            //2.2 尝试26种字符替换
            for (char j = 'a'; j <= 'z'; j++) {

                if (j == odd){
                    continue;
                }

                //2.3 替换
                ch[i] = j;

                //2.4 替换后的先单词
                String newWord = String.valueOf(ch);

                //2.5 判断是否存在
                if (wordSet.contains(newWord)){
                    if (newWord.equals(endWord)){
                        return true;
                    }

                    //如果之前没有被访问,则加入到队列,供下次遍历判断
                    //并标记为已经访问
                    if (!visited.contains(newWord)){
                        queue.offerLast(newWord);
                        visited.add(newWord);
                    }
                }
            }

            //还原
            ch[i] = odd;
        }
        return false;
    }
}

去力扣试试:



结束语:
Ok,就是本篇文章的全部内容了。
如果各位有不懂的地方,欢迎发消息给小编,小编会进行详细地解答。
最后,请屏幕前的各位吴彦祖和刘亦菲们,动动你们的小手,给小编一个

文章转载自皮皮克克,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论