LeetCode刷题日记(Day12)

LeetCode两题解题思路与实现
博客围绕LeetCode的两道题展开。Problem 78要求找出给定数组的所有子集,通过递归算法,分别找出不同长度子集并存储。Problem 79是在二维网格中查找单词,使用深度优先搜索算法,注意标记访问点并可重复遍历。

Problem 78. Subsets

  • 题目描述
    Given a set of distinct integers, nums, return all possible subsets (the power set).

    Note: The solution set must not contain duplicate subsets.

    Example:

    Input: nums = [1,2,3]
    Output:
    [
      [3],
      [1],
      [2],
      [1,2,3],
      [1,3],
      [2,3],
      [1,2],
      []
    ]
    
  • 解题思路
    假设输入的数组为 nums,且 nums 的大小为 n。则要找出 nums 的所有子集,我们就要分别找出 nums 中长度为0(空集)、1、2……n的子集,将这些子集存储在 res 中,即可得到 nums 的所有子集。

    假设 nums 中的元素为 nums[0]、nums[1]、……nums[n-1],若要找出 nums 中长度为 len 的子集,其中len <= n,可以先将 nums[0] 加入到子集 sub 中,再从 nums[1] 到 nums[n-1] 中选择 len-1 个加入到 sub;随后将 nums[1] 加入到子集 sub 中,再从 nums[2] 到 nums[n-1] 中选择 len-1 个加入到 sub 中……以此类推,就能将所有长度为 len 的子集 sub 存储到 res 中。

    下面给出了用递归实现上述算法的代码:

  • 代码实现

class Solution {
public:
    vector<vector<int> > subsets(vector<int>& nums) {
        vector<vector<int> > res;
        vector<int> sub;
        sort(nums.begin(), nums.end());
        for(int i = 0; i <= nums.size(); ++i){
            helper(res, sub, nums, 0, i);
        }
        return res;
    }
    void helper(vector<vector<int> >& res, vector<int> &sub, vector<int> &nums, int star, int len){
        if(len == 0){
            res.push_back(sub);
            return ;
        }
        for(int i = star; i < nums.size(); ++i){
            sub.push_back(nums[i]);
            helper(res, sub, nums, i+1, len-1);
            sub.pop_back();
        }
    }
};

Problem 79. Word Search

  • 题目描述
    Given a 2D board and a word, find if the word exists in the grid.

    The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

    Example:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.
  • 解题思路
    本题用深度优先搜索算法BFS即可,其中row和col表示输入board的大小,isVisited用来表示board中的每一个点有没有被访问过(访问则置为true),index表示当前访问的word的下标。
    需要注意的一点是,board中的每一个点是可以重复遍历的,所以在以遍历board[i][j]时,先将isVisited[i][j]置为true,遍历完之后再置为false。

  • 代码实现

class Solution {
public:
    bool exist(vector<vector<char> >& board, string word) {
        int row = board.size();
        if(row == 0 || word.size() == 0)
            return false;
        int col = board[0].size();
        if(col == 0)
            return false;
        for(int i = 0; i < row; ++i)
            for(int j = 0; j < col; ++j)
                if(board[i][j] == word[0]){
                    vector<vector<bool> > isVisited(row, vector<bool>(col, false));
                    if(bfs(board, row, col, i, j, word, 0, isVisited))
                        return true;
                }
        return false;
                
    }

    bool bfs(vector<vector<char> >& board, int row, int col, int i, int j, string & word, int index, vector<vector<bool> >& isVisited){
        if(i < 0 || i >= row || j < 0 || j >= col)
            return false;
        if(isVisited[i][j] || word[index] != board[i][j])
            return false;
        isVisited[i][j] = true;
        if(index == word.size()-1)
            return true;
        
        int dire[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

        bool res = false;
        for(int k = 0; k < 4; ++k){
            res = res || bfs(board, row, col, i + dire[k][0], j + dire[k][1], word, index + 1, isVisited);
        }
        isVisited[i][j] = false;
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值