leetcode BFS部分面试题

192 阅读2分钟

leetcode 279 组成整数的最小平方数数量

原题内容:

For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, 
return 2 because 13 = 4 + 9.

解法一:可以将每个整数看成图中的一个节点,如果两个整数之差为一个平方数,那么这两个整数所在的节点就有一条边。

要求解最小的平方数数量,就是求解从节点 n 到节点 0 的最短路径。

package leetcode209;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Solution {


    /**
     * @Author chengxingyuan
     * @Description 计算平方数个数
     * @Date 10:05 2019/8/29
     * @Param
     * @return
     */
    public int numSquares(int n){
        List<Integer> squares =generateSquares(n);
        Queue<Integer> queue = new LinkedList<>();

        queue.add(n);
        //标记从当前第n个节点出发,访问节点差值为平方数的标记
        boolean[] marked = new boolean[n+1];
        marked[n] = true;
        int level = 0;
        while(!queue.isEmpty()){
            int size = queue.size();
            level++;
            while (size-- >0){
                //取出头元素,在队列中删除
                int cur = queue.poll();
                for (int s:squares){
                    int next = cur-s;
                    if (next<0){
                        break;
                    }if (next ==0){
                        //如果差值为0,说明不能拆分,返回差值访问次数
                        return level;
                    }if (marked[next]){
                        //已经访问过
                        continue;
                    }
                    marked[next] = true;
                    queue.add(next);
                }
            }
        }
        return n;
    }

    /**
     * @Author chengxingyuan
     * @Description 生成小于n的平方数个数
     * @Date 10:38 2019/8/29
     * @Param
     * @return
     */
    private List<Integer> generateSquares(int n) {
        List<Integer> squares = new ArrayList<>();
        int square = 1;
        int diff = 3;
        while (square <= n) {
            squares.add(square);
            square += diff;
            diff += 2;
        }
        return squares;
    }
}

leetcode 219 最短单词路径

Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

Output: 0
Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
题目描述:找出一条从 beginWord 到 endWord 的最短路径,每次移动规定为改变一个字符,并且改变之后的字符串必须在 wordList 中。
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
    wordList.add(beginWord);
    int N = wordList.size();
    int start = N - 1;
    int end = 0;
    while (end < N && !wordList.get(end).equals(endWord)) {
        end++;
    }
    if (end == N) {
        return 0;
    }
    List<Integer>[] graphic = buildGraphic(wordList);
    return getShortestPath(graphic, start, end);
}

//建图
private List<Integer>[] buildGraphic(List<String> wordList) {
    int N = wordList.size();
    List<Integer>[] graphic = new List[N];
    //把各个需要转换的序列分成几个list 比如
    "hit" -> "hot" -> "dot" -> "dog" -> "cog",
    "hot" -> "dot" -> "dog"
    依次判断从当前关键字出发是否能与下个关键字连接
    for (int i = 0; i < N; i++) {
        graphic[i] = new ArrayList<>();
        for (int j = 0; j < N; j++) {
            if (isConnect(wordList.get(i), wordList.get(j))) {
                graphic[i].add(j);
            }
        }
    }
    return graphic;
}

private boolean isConnect(String s1, String s2) {
    int diffCnt = 0;
    for (int i = 0; i < s1.length() && diffCnt <= 1; i++) {
        if (s1.charAt(i) != s2.charAt(i)) {
            diffCnt++;
        }
    }
    return diffCnt == 1;
}

//获取最短路径
private int getShortestPath(List<Integer>[] graphic, int start, int end) {
    Queue<Integer> queue = new LinkedList<>();
    boolean[] marked = new boolean[graphic.length];
    queue.add(start);
    marked[start] = true;
    int path = 1;
    //沿用上一题的做法,不同的地方在于这里已经保存了第i个节点的权重,不需要进行计算,判断是否已经在本次序列中访问过这个节点即可
    while (!queue.isEmpty()) {
        int size = queue.size();
        path++;
        while (size-- > 0) {
            int cur = queue.poll();
            for (int next : graphic[cur]) {
                if (next == end) {
                    return path;
                }
                if (marked[next]) {
                    continue;
                }
                marked[next] = true;
                queue.add(next);
            }
        }
    }
    return 0;
}