回溯 & 单词拆分 & N 皇后

124 阅读1分钟

前言

“这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战

  1. 140. 单词拆分 II

  2. 51. N 皇后

140. 单词拆分 II

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。

说明:

  • 分隔时可以重复使用字典中的单词。
  • 你可以假设字典中没有重复的单词。

示例 1:

输入: s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
输出: [
  "cats and dog",
  "cat sand dog"
]

类似IP复原

思路分析: 回溯

  • 已经做出的选择(记录在 temp 中)

  • 结束条件(字符串遍历结束)

  • 可以做出的选择(从 index 向后尝试截取 长度为 1到 maxWordLength 的字符串判断)

AC 代码

    List<List<String>> res = new ArrayList<>();
    int maxWordLen;

    public List<String> wordBreak(String s, List<String> wordDict) {

        Collections.sort(wordDict, (a, b) -> b.length() - a.length());
        maxWordLen = wordDict.get(0).length();
        List<String> ans = new ArrayList<>();

        dfs(s, 0, wordDict, new ArrayList<>());

        for (List<String> strings : res) {
            StringBuilder sb = new StringBuilder();
            for (String ss : strings) {
                sb.append(ss).append(" ");
            }
            ans.add(sb.substring(0, sb.length() - 1));
        }
        return ans;
    }

    void dfs(String s, int index, List<String> wordList, List<String> temp) {

        if (index == s.length()) {
            res.add(new ArrayList<>(temp));
            return;
        }

        for (int i = 1; i <= maxWordLen && index + i <= s.length(); i++) {
            String data = s.substring(index, index + i);
            if (wordList.contains(data)) {
                temp.add(data);
                dfs(s, index + i, wordList, temp);
                temp.remove(temp.size() - 1);
            }
        }
    }

51. N 皇后

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。 示例 2:

输入:n = 1 输出:[["Q"]]  

提示:

1 <= n <= 9 皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。

思路分析: 回溯

  • 已经做出的选择(记录在 chars 中)
  • 结束条件(n 皇后 遍历到第 n 行)
  • 可以做出的选择(尝试在每一行 每一列的位置填入 皇后)

AC 代码

    int row;
    List<List<String>> queens = new ArrayList<>();

    public List<List<String>> solveNQueens(int n) {

        char[][] chars = new char[n][n];

        for (char[] ch : chars) {
            Arrays.fill(ch, '.');
        }
        row = n;
        dfs(0, chars);
        return queens;
    }

    boolean check(char[][] chars, int row, int col) {

        for (int i = 0; i < row; i++) {
            if (chars[i][col] == 'Q') return false;
        }

        int i = row - 1;
        int j = col - 1;

        while (i >= 0 && j >= 0) {
            if (chars[i--][j--] == 'Q') return false;
        }

        i = row - 1;
        j = col + 1;

        while (i >= 0 && j < chars[0].length && j >= 0) {


            if (chars[i--][j++] == 'Q') return false;

        }

        return true;
    }

    void dfs(int curRow, char[][] temp) {
        if (curRow == row) {
            queens.add(convert(temp));
            return;
        }

        for (int j = 0; j < temp[0].length; j++) {
            temp[curRow][j] = 'Q';
            if (check(temp, curRow, j)) {
                dfs(curRow + 1, temp);
            }
            temp[curRow][j] = '.';
        }
    }

        List<String> convert(char[][] chars) {
        List<String> ans = new ArrayList<>();

        for (char[] ch : chars) {
            StringBuilder sb = new StringBuilder();
            for (char c : ch) {
                sb.append(c);
            }
            ans.add(sb.toString());
        }
        return ans;
    }