12(79) 矩阵中的路径

给定一个 $m \times n$ 二维字符网格 $board$ 和一个字符串单词 $word$ 。如果 $word$ 存在于网格中,返回 $true$ ;否则,返回 $false$ 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:

img

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true

示例 2:

img

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true

示例 3:

img

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

提示:

  • $m == board.length$
  • $n = board[i].length$
  • $1 <= m, n <= 6$
  • $1 <= word.length <= 15$
  • $board$ 和 $word$ 仅由大小写英文字母组成

题解

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        rows = board.size();
        cols = board[0].size();
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
                if(dfs(board,word,i,j,0))return true;
            }
        }
        return false;
    }
private:
    int rows, cols;
    bool dfs(vector<vector<char>>& board, string word, int i, int j, int k){
        if(i>=rows || i<0 || j>=cols || j<0 || board[i][j]!=word[k])return false;
        if(k==word.size()-1)return true;
        board[i][j]='\0';
        bool res=dfs(board, word, i+1, j, k+1) || dfs(board, word, i-1, j, k+1) ||
                    dfs(board, word, i, j+1, k+1) || dfs(board, word, i, j-1, k+1);
        board[i][j]=word[k];
        return res;
    }
};

M13 机器人的运动范围

地上有一个m行n列的方格,从坐标 $[0,0]$ 到坐标 $[m-1,n-1]$ 。一个机器人从坐标 $[0, 0] $的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

示例 1:

输入:m = 2, n = 3, k = 1
输出:3

示例 2:

输入:m = 3, n = 1, k = 0
输出:1

提示:

  • $1 <= n,m <= 100$
  • $0 <= k <= 20$

题解

class Solution {
public:
    int movingCount(int m, int n, int k) {
        vector<vector<bool>> visited(m, vector<bool>(n,0));
        return dfs(0,0,0,0,visited,m,n,k);
    }
private:
    int dfs(int i, int j, int si, int sj, vector<vector<bool>> &visited, int m, int n, int k){
        if(i>=m || j>=n || k<si+sj || visited[i][j])return 0;
        visited[i][j]=true;
        return 1+dfs(i+1, j, (i+1)%10!=0?si+1:si-8,sj,visited,m,n,k)+
                dfs(i,j+1,si,(j+1)%10!=0?sj+1:sj-8,visited,m,n,k);
    }
};

38 字符串的排列

输入一个字符串,打印出该字符串中字符的所有排列。

你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

示例:

输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]

限制:

1 <= s 的长度 <= 8

题解

class Solution {
public:
    vector<string> permutation(string s) {
        dfs(s, 0);
        return res;
    }
private:
    vector<string> res;
    void dfs(string s, int x){
        if(x==s.size()-1){
            res.push_back(s);
            return;
        }
        set<int> st;
        for(int i=x;i<s.size();i++){
            if(st.find(s[i])!=st.end())continue;//重复则剪枝
            st.insert(s[i]);
            swap(s[i], s[x]);//交换,将s[i]固定在x位
            dfs(s, x+1);//固定x+1各字符
            swap(s[i],s[x]);//恢复交换
        }
    }
};