0
点赞
收藏
分享

微信扫一扫

深度优先(DFS)

SDKB英文 2022-01-06 阅读 106

1 dfs简介

        深度优先其实就是回溯算法,也就是暴力穷举,所以效率并不高。深度优先尝尝使用递归来进行编码,套路如下:做出选择;递归;撤销选择;并且需要注意递归的退出点就可以了。

2 力扣题目

2.1 岛屿的最大面积

695. 岛屿的最大面积

class Solution {
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int maxArea = 0;
        for (int i = 0; i < grid.size(); ++i)
        {
            for (int j = 0; j < grid[0].size(); ++j)
            {
                if (grid[i][j])
                {
                    maxArea = std::max(maxArea, helper(grid, i, j));
                }                
            }
        }

        return maxArea;
    }

    int helper(vector<vector<int>>& grid, int r, int c)
    {
        int area = 0;
        if (r >=0 && r < grid.size() && c >=0 && c < grid[0].size() && grid[r][c])
        {
            area += 1;
            grid[r][c] = 0;
            if ((c-1) >=0 && grid[r][c-1])
            {
                area += helper(grid, r, c-1);                
            }

            if ((c+1) < grid[0].size() && grid[r][c+1])
            {
                area += helper(grid, r, c+1);
            }     

            if ((r-1) >=0 && grid[r-1][c])
            {
                area += helper(grid, r-1, c);
            }   

            if ((r+1) < grid.size() && grid[r+1][c])
            {
                area += helper(grid, r+1, c);
            }                           
        }

        return area;
    }
};

2.2 不含重复数字的全排列

46. 全排列

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<int> path;
        vector<vector<int>> result;
        dfs(nums,path,result);
        return result;
    }

    void dfs(vector<int>& nums, vector<int>& path, vector<vector<int>>& result)
    {
        if (nums.size() == path.size())
        {
            result.emplace_back(path);
            return;
        }

        for (int n : nums)
        {
            if (std::find(path.begin(), path.end(), n) != path.end())
            {
                continue;
            }

            path.push_back(n);
            dfs(nums,path,result);
            path.pop_back();
        }
    }
};

47. 全排列 II

class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<int> path, index;
        vector<vector<int>> result;
        dfs(nums,index,path,result);
        std::sort(result.begin(),result.end());
        result.resize(std::distance(result.begin(),std::unique(result.begin(),result.end())));
        return result;
    }

    void dfs(vector<int>& nums, vector<int>& index, vector<int>& path, vector<vector<int>>& result)
    {
        if (nums.size() == path.size())
        {
            result.emplace_back(path);
            return;
        }

        for (int i=0;i<nums.size();++i)
        {
            if (std::find(index.begin(), index.end(), i) != index.end())
            {
                continue;
            }            

            index.push_back(i);
            path.push_back(nums[i]);
            dfs(nums,index,path,result);
            index.pop_back();
            path.pop_back();
        }
    }  
};

2.3 二叉树中和为某一值的路径

剑指 Offer 34. 二叉树中和为某一值的路径

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> pathSum(TreeNode* root, int target) {
        vector<vector<int>> r;
        vector<int> path;
        backTrack(r,path,root,target);
        return r;
    }

    void backTrack(vector<vector<int>>& r, vector<int>& path, TreeNode* root, int target)
    {
        if (root)
        {           
            path.push_back(root->val); 
            if (root->val == target && !root->left && !root->right)
            {
                r.push_back(path);
            }

            backTrack(r,path,root->left,target-root->val);
            backTrack(r,path,root->right,target-root->val);
            path.pop_back();
        }
    }
};

2.4 二叉树的最近公共祖先

剑指 Offer 68 - 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:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        vector<TreeNode*> path_p = getPath(root, p);
        vector<TreeNode*> path_q = getPath(root, q);
        TreeNode* ancestor;
        for (int i = 0; i < path_p.size() && i < path_q.size(); ++i) 
        {
            if (path_p[i] == path_q[i]) 
            {
                ancestor = path_p[i];
            }
            else 
            {
                break;
            }
        }
        return ancestor;        
    }

    vector<TreeNode*> getPath(TreeNode* root, TreeNode* target) {
        vector<TreeNode*> path;
        dfs(root, target, path);
        return path;
    }

    bool dfs(TreeNode* root, TreeNode* target, vector<TreeNode*>& path)
    {
        bool find = false;
        do 
        {
            if (root)
            {
                path.push_back(root);
                if (root == target)
                {
                    find = true;
                    break;
                }

                if (dfs(root->left, target, path) || dfs(root->right, target, path))
                {
                    find = true;
                    break;
                }

                path.pop_back();
            }
        } while(0);

        return find;
    }
};

2.5 二叉搜索树转换成双向链表

剑指 Offer 36. 二叉搜索树与双向链表

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;

    Node() {}

    Node(int _val) {
        val = _val;
        left = NULL;
        right = NULL;
    }

    Node(int _val, Node* _left, Node* _right) {
        val = _val;
        left = _left;
        right = _right;
    }
};
*/
class Solution {
public:
    Node* treeToDoublyList(Node* root) {
        if (!root)
        {
            return root;
        }

        Node *pre = NULL, *head = NULL;
        backTrack(root, pre, head);
        head->left = pre;
        pre->right = head;

        return head;
    }

    void backTrack(Node* cur, Node*& pre, Node*& head)
    {
        if (!cur)
        {
            return;
        }

        backTrack(cur->left, pre, head);
        if (!pre)
        {
            head = cur;
        }
        else
        {
            pre->right = cur;
            cur->left = pre;
        }

        pre = cur;
        backTrack(cur->right, pre, head);
    }
};

2.6 矩阵中的路径

剑指 Offer 12. 矩阵中的路径

class Solution {
public:
	bool exist(vector<vector<char>>& board, string word) {
		bool find = false;
        int row = board.size(), col = board[0].size();
		vector<vector<bool>> visited(row, vector<bool>(col, false));
		do
		{
			if (board.empty())
			{
				if (word.empty())
				{
					find = true;
				}
				break;
			}

            for (int r = 0; r < row; ++r)
            {
                for (int c = 0; c < col; ++c)
                {
                    if (backTrack(board, word, visited, 0, r, c))
                    {
                        find = true;
                        return find;
                    }
                }
            }
		} while (0);

		return find;
	}

	bool backTrack(vector<vector<char>>& board, const string& word, vector<vector<bool>>& visited, int pos, int r, int c)
	{
		bool find = false;
		do
		{
			if (pos == word.size())
			{
				find = true;
				break;
			}

			if (word.empty())
			{
				break;
			}

			int row = board.size(), col = board[0].size();
            char ch = word[pos];
            if (r >= 0 && r < row && c >= 0 && c < col)
            {
                if (visited[r][c])
                {
                    break;
                }

                if (ch != board[r][c])
                {
                    break;
                }

                visited[r][c] = true;
                if (backTrack(board, word, visited, pos+1, r-1, c)
                    || backTrack(board, word, visited, pos+1, r+1, c)
                    || backTrack(board, word, visited, pos+1, r, c-1)
                    || backTrack(board, word, visited, pos+1, r, c+1))
                {
                    find = true;
                    break;
                }
                visited[r][c] = false;
            }
		} while (0);

		return find;
	}
};

2.7 字符串的排列

剑指 Offer 38. 字符串的排列

class Solution {
public:
    //方法一
    // vector<string> rec;
    // vector<int> vis;

    // void backtrack(const string& s, int i, int n, string& perm) {
    //     if (i == n) {
    //         rec.push_back(perm);
    //         return;
    //     }
    //     for (int j = 0; j < n; j++) {
    //         if (vis[j] || (j > 0 && !vis[j - 1] && s[j - 1] == s[j])) {
    //             continue;
    //         }
    //         vis[j] = true;
    //         perm.push_back(s[j]);
    //         backtrack(s, i + 1, n, perm);
    //         perm.pop_back();
    //         vis[j] = false;
    //     }
    // }

    // vector<string> permutation(string s) {
    //     int n = s.size();
    //     vis.resize(n);
    //     sort(s.begin(), s.end());
    //     string perm;
    //     backtrack(s, 0, n, perm);
    //     return rec;
    // }


    //方法二
    unordered_set<string> rec;
    void helper(string& s, int beginIndex, int endIndex)
    {
        if (beginIndex == endIndex)
        {
            rec.insert(s);
            return;
        }

        for (int i=beginIndex;i<=endIndex;++i)
        {
            char c = s[i];
            s[i] = s[beginIndex];
            s[beginIndex] = c;

            helper(s, beginIndex+1, endIndex);
            
            c = s[i];
            s[i] = s[beginIndex];
            s[beginIndex] = c;            
        }
    }

    vector<string> permutation(string s) {
        int n = s.size();
        helper(s, 0, n-1);
        return vector<string>(rec.begin(), rec.end());
    }    
};

2.8

2.9

2.10

举报

相关推荐

0 条评论