Bootstrap

LeetCode打卡--DFS专题

DFS专题

LeetCode 784. Letter Case Permutation

class Solution {
public:
    vector<string> res;

    vector<string> letterCasePermutation(string S) {
        dfs(S, 0);
        return res;
    }

    void dfs(string S, int u)
    {
        if(u == S.size())
        {
            res.push_back(S);
            return;
        }

        //不变化大小写
        dfs(S, u + 1);

        //0是48,A是65,a是97,这里因为只有数字和字母,所以可以判定
        if(S[u] >= 'A')
        {
            //巧妙的是,用32异或大小写
            S[u] ^= 32;
            dfs(S, u+1);
        }
    }
};

LeetCode 77. Combinations

class Solution {
public:
    vector<vector<int> > ans;

    vector<vector<int>> combine(int n, int k) {
        vector<int> path;
        dfs(path, 1, n, k);
        return ans;
    }

    void dfs(vector<int> &path, int start, int n, int k)
    {
        //如果k为0,说明找到了终止条件,把当前方案加入到ans中
        if(!k)
        {
            ans.push_back(path);
            return;
        }

        //依次枚举
        for(int i = start; i <= n; i++)
        {
            path.push_back(i);
            dfs(path, i + 1, n, k-1);
            path.pop_back();
        }
    }
};

LeetCode 257. Binary Tree Paths

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<string> ans;

    vector<string> binaryTreePaths(TreeNode* root) {
        string path;
        dfs(root, path);
        return ans;
    }

    void dfs(TreeNode* root, string path)
    {
        if(!root)return;
        //除了第一个,后面的都要加上->
        if(path.size())path += "->";
        path += to_string(root->val);

        //如果左右子树都是空的,那么则到了叶子结点了
        if(!root->left && !root->right)ans.push_back(path);
        else
        {
            dfs(root->left, path);   
            dfs(root->right, path);   
        }
    }
};

LeetCode 93. Restore IP Addresses

class Solution {
public:
    vector<string> ans;
    vector<int> path;

    vector<string> restoreIpAddresses(string s) {
        dfs(0,0,s);
        return ans;
    }

    void dfs(int u, int k, string &s)
    {
        //如果说字符串遍历完了,而且k为4,则把当前方案加到ans中去
        if(u == s.size())
        {
            if(k == 4)
            {
                string ip = to_string(path[0]);
                for(int i = 1; i < 4; i++)
                    ip += '.' + to_string(path[i]);
                ans.push_back(ip);
            }
            return;
        }

        //提前去掉,k超了
        if(k > 4)return;

        unsigned int t = 0;
        //暴力枚举所有的可能性
        for(int i = u; i < s.size();  i++)
        {
            t = t * 10 + s[i] - '0';
            if(t >=0 && t < 256)
            {
                path.push_back(t);
                dfs(i + 1, k + 1, s);
                //还原现场,以备下一次枚举
                path.pop_back();
            }
            if(!t)break;
        }

    }
};

LeetCode 95. Unique Binary Search Trees II

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<TreeNode*> generateTrees(int n) {
        if(!n)return vector<TreeNode*>();
        return dfs(1,n);
    }

    vector<TreeNode*> dfs(int l, int r)
    {
        vector<TreeNode*> res;
        if(l > r)
        {
            res.push_back(NULL);
            return res;
        }

        //这里是枚举根结点,剩下的分为左子树和右子树,
        for(int i = l; i <= r; i++)
        {
            auto left = dfs(l, i-1), right = dfs(i+1, r);
            for(auto &lt : left)
                for(auto &rt : right)
                {
                    auto root = new TreeNode(i);
                    root->left = lt, root->right = rt;
                    res.push_back(root);
                }
        }
        return res;
    }
};

LeetCode 394. Decode String

class Solution {
public:
    string decodeString(string s) {
        string res;
        for(int i = 0; i < s.size();)
        {
            //如果不是数字,直接加入
            if(!isdigit(s[i]))res+=s[i++];
            else
            {
                int k = 0;
                //如果是数字,那么看下是数字多少,取出数字
                while(isdigit(s[i]))k = k * 10 + s[i++] - '0';
                int j = i + 1, sum = 1;
                //找到匹配的边界
                while(sum > 0)
                {
                    if(s[j]=='[')sum++;
                    if(s[j]==']')sum--;
                    j++;
                }
                string r = decodeString(s.substr(i+1, j-i-2));
                while(k--)res += r;
                i = j;
            }
        }
        return res;
    }
};

LeetCode 341. Flatten Nested List Iterator

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * class NestedInteger {
 *   public:
 *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
 *     bool isInteger() const;
 *
 *     // Return the single integer that this NestedInteger holds, if it holds a single integer
 *     // The result is undefined if this NestedInteger holds a nested list
 *     int getInteger() const;
 *
 *     // Return the nested list that this NestedInteger holds, if it holds a nested list
 *     // The result is undefined if this NestedInteger holds a single integer
 *     const vector<NestedInteger> &getList() const;
 * };
 */
class NestedIterator {
public:
    vector<int> seq;
    int cnt = 0;

    NestedIterator(vector<NestedInteger> &nestedList) {
        dfs(nestedList);
    }

    void dfs(vector<NestedInteger> &nestedList)
    {
        for(auto &l : nestedList)
        {
            if(l.isInteger())seq.push_back(l.getInteger());
            else dfs(l.getList());
        }
    }

    int next() {
        return seq[cnt++];
    }

    bool hasNext() {
        return cnt < seq.size();
    }
};

/**
 * Your NestedIterator object will be instantiated and called as such:
 * NestedIterator i(nestedList);
 * while (i.hasNext()) cout << i.next();
 */

LeetCode 756. Pyramid Transition Matrix

class Solution {
public:
    vector<char> allows[7][7];

    bool pyramidTransition(string bottom, vector<string>& allowed) {
        for(auto allow : allowed)
        {
            //将可能的方案数存储下来
            int a = allow[0]-'A', b = allow[1]-'A', c = allow[2];
            allows[a][b].push_back(c);
        }
        return dfs(bottom, "");
    }

    bool dfs(string &last, string now)
    {
        //只有一个,则找到了
        if(last.size() == 1)return true;
        //方案齐了,进入下一层
        if(now.size()+1 == last.size())return dfs(now, "");
        int a = last[now.size()] - 'A', b = last[now.size() + 1] - 'A';
        for(auto c : allows[a][b])
        {
            if(dfs(last, now + c))
                return true;
        }

        return false;
    }
};

LeetCode 79. Word Search

class Solution {
public:
    int n, m;
    vector<vector<bool>> st;
    vector<vector<char>> boards;
    string words;

    bool exist(vector<vector<char>>& board, string word) {
        words = word;
        boards = board;
        n = board.size();
        m = board[0].size();
        st = vector<vector<bool>> (n, vector<bool>(m,false));

        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
            {
                if(board[i][j] == word[0])
                {
                    //只要有一个方案可行就可了
                    if(dfs(i,j,1))
                        return true;
                }
            }
        //所有的方案都不可行
        return false;
    }

    bool dfs(int x, int y, int u)
    {
        if(u == words.size())return true;
        st[x][y] = true;
        int dx[4] = {-1, 0, 1, 0};
        int dy[4] = {0, 1, 0, -1};
        for(int i = 0; i < 4; i++)
        {
            int a = x + dx[i], b = y + dy[i];
            if(a >= 0 && a < n && b >= 0 && b < m && !st[a][b] && boards[a][b] == words[u])
            {
                if(dfs(a,b, u+1))return true;
            }
        }
        st[x][y] = false;
        return false;
    }


};

LeetCode 464. Can I Win

class Solution {
public:
    bool canIWin(int maxChoosableInteger, int desiredTotal) {
        int status = 0;
        //谁先拿,谁赢
        if(desiredTotal <= 1)return true;
        //所有数都拿也超过不了,所以没法赢
        if(maxChoosableInteger*(maxChoosableInteger+1) < desiredTotal*2)return false;

        vector<unordered_map<int, bool>> dp(desiredTotal+1);
        return Caniwin(status, dp, maxChoosableInteger, desiredTotal);
    }

    bool Caniwin(int status, vector<unordered_map<int, bool>> &dp, int maxChoosableInteger, int desiredTotal)
    {
        if(dp[desiredTotal].count(status))
            return dp[desiredTotal][status];
        for(int i = maxChoosableInteger -1; i >= 0; --i)
        {
            if(!(status & (1 << i)))
            {
                status |= (1 << i);
                if(i+1 >= desiredTotal || !Caniwin(status, dp, maxChoosableInteger, desiredTotal-i-1) )
                {
                    dp[desiredTotal][status] = true;
                    return true;
                }
                status ^= (1<<i);
            }
        }
        dp[desiredTotal][status] = false;
        return false;
    }
};
//不理解
;