week5

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:

输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

百分之80 的暴搜题目是要回溯(恢复先前状态)

class Solution {
public:
    string chars[8]={"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

    vector<string> letterCombinations(string digits) {
        if(digits.empty()) return vector<string>();

        vector<string> state(1,"");
        for(auto u:digits)
        {
            vector<string> now;
            for(auto c:chars[u-'0'-2])
                for(auto s:state)
                    now.push_back(s+c);
            state=now;
        }

        return state;
    }
};

 

79. 单词搜索

给定一个二维网格和一个单词,找出该单词是否存在于网格中。

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

 

示例:

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

给定 word = "ABCCED", 返回 true
给定 word = "SEE", 返回 true
给定 word = "ABCB", 返回 false
class Solution {
public:
    int n,m;
    int x[4]={0,0,1,-1},y[4]={-1,1,0,0};
    bool exist(vector<vector<char>>& board, string word) {
        if(board.empty() || board[0].empty()) return false;

        m=board.size();n=board[0].size();

        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
                if(dfs(board,word,i,j,0))
                        return true;
        }
        return false;
    }

    bool dfs(vector<vector<char>>& board, string &word,int i,int j,int u)
    {
        if(board[i][j]!=word[u]) return false;
        if(u==word.size()-1) return true;

        board[i][j]='.';
        for(int k=0;k<4;k++)
        {
            int X=i+x[k];
            int Y=j+y[k];
            if(X>=0 && X<m && Y>=0 && Y<n)
            {
                if(dfs(board,word,X,Y,u+1))
                    return true;
            }
        }
        board[i][j]=word[u];
        return false;
    }
};

46. 全排列

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
class Solution {
public:
    int n;
    vector<bool> st;
    vector<vector<int>> ans;
    vector<int> path;
   
    vector<vector<int>> permute(vector<int>& nums) {
        n=nums.size();
        st=vector<bool>(n);
        dfs(nums,0);
        return ans;
    }

    void dfs(vector<int>& nums,int u)
    {
        if(u==n)
        {
            ans.push_back(path);
            return;
        }
        for(int i=0;i<n;i++)
            if(!st[i])
            {
                st[i]=true;
                path.push_back(nums[i]);
                dfs(nums,u+1);
                path.pop_back();
                st[i]=false;
            }
    }
};

 

47. 全排列 II

给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

输入: [1,1,2]
输出:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]
class Solution {
public:
    int n;
    vector<bool>st;
    vector<int> path;
    vector<vector<int>>ans;
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        n=nums.size();
        sort(nums.begin(),nums.end());
        st=vector<bool>(n);
        path=vector<int>(n);
        dfs(nums,0,0);
        return ans;
    }

    void dfs(vector<int>& nums,int u,int start)
    {
        if(u==n)
        {
            ans.push_back(path);
            return;
        }
        for(int i=start;i<n;i++)
        {
            if(st[i]==false)
            {
                st[i]=true;
                path[i]=nums[u];
                dfs(nums,u+1,u+1<n && nums[u+1]==nums[u]?i+1:0);
                st[i]=false;
            }
        }
    }

};

 

class Solution {
public:
    int n;
    vector<int>path;
    vector<vector<int>>ans;
    vector<vector<int>> subsets(vector<int>& nums) {
        n=nums.size();

        dfs(nums,0);
        return ans;
    }
    void dfs(vector<int>& nums,int u)
    {
        if(u==n)
        {
            ans.push_back(path);
            return;
        }
        path.push_back(nums[u]);
        dfs(nums,u+1);
        path.pop_back();
        dfs(nums,u+1);
    }
};

 

78. 子集

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
class Solution {
public:
\
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>>res;
        for(int i=0;i< 1<<nums.size();i++)
        {
            vector<int>now;
            for(int j=0;j<nums.size();j++)
            {
                if(i>>j & 1)
                    now.push_back(nums[j]);
            }
            res.push_back(now);
        }
        return res;
    }
};

 

90. 子集 II

给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: [1,2,2]
输出:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
class Solution {
public:

    vector<int>path;
    vector<vector<int>>ans;

    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        dfs(nums,0);
        return ans;
    }

    void dfs(vector<int>& nums,int u)
    {
        if(u==nums.size())
        {
            ans.push_back(path);
            return;
        }
        int k=0;
        while(u + k < nums.size() && nums[u]==nums[u+k]) 
                k++;

        for(int i=0;i<=k;i++)
        {
            dfs(nums,u+k);
            path.push_back(nums[u]);
        }
        for(int i=0;i<=k;i++) 
            path.pop_back();

    }
};
class Solution {
public:
    vector<vector<int>>ans;
    vector<int>path;
    vector<vector<int>> combinationSum3(int k, int n) {
        dfs(k,1,n);
        return ans;
    }

    void dfs(int k,int start,int n)
    {
        if(!k)
        {
            if(!n) ans.push_back(path);
            return ;
        }
        for(int i=start;i<=9;i++)
        {
            path.push_back(i);
            dfs(k-1,i+1,n-i);
            path.pop_back();
        }
    }
};

52. N皇后 II

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

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回 n 皇后不同的解决方案的数量。

 

class Solution {
public:

    int ans=0,n;
    vector<bool> col,u,du;
    int totalNQueens(int _n) {
        n=_n;
        col=vector<bool>(n);
        u=du=vector<bool>(2*n);
        dfs(0);
        return ans;
    }

    void dfs(int k)
    {
        if(k==n)
        {
            ans++;
            return;
        }
        for(int i=0;i<n;i++)
        {
            if(!col[i] && !u[i+k] && !du[i-k+n])
            {
                col[i]=u[i+k]=du[i-k+n]=true;
                dfs(k+1);
                col[i]=u[i+k]=du[i-k+n]=false;
            }
        }
    }

};

 

class Solution {
public:

    bool col[9][9]={0},row[9][9]={0},cell[3][3][9]={0};
    void solveSudoku(vector<vector<char>>& board) {
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {
                char c=board[i][j];
                if(c!='.')
                {
                    int t=c-'1';
                    row[i][t]=col[j][t]=cell[i/3][j/3][t]=true;
                }
            }
        }
        dfs(board,0,0);
    }

    bool dfs(vector<vector<char>>& board,int x,int y)
    {
        if(y==9) x++,y=0;
        if(x==9) return true;
        if(board[x][y]!='.') return dfs(board,x,y+1);
        for(int i=0;i<9;i++)
        {
            if(!row[x][i] && !col[y][i] && !cell[x/3][y/3][i])
            {
                row[x][i]=col[y][i]=cell[x/3][y/3][i]=true;
                board[x][y]='1'+i;
                if(dfs(board,x,y+1)) return true;
                row[x][i]=col[y][i]=cell[x/3][y/3][i]=false;
                board[x][y]='.';

            }
        }
        return false;

    }
};

 

473. 火柴拼正方形

还记得童话《卖火柴的小女孩》吗?现在,你知道小女孩有多少根火柴,请找出一种能使用所有火柴拼成一个正方形的方法。不能折断火柴,可以把火柴连接起来,并且每根火柴都要用到。

输入为小女孩拥有火柴的数目,每根火柴用其长度表示。输出即为是否能用所有的火柴拼成正方形。

示例 1:

输入: [1,1,2,2,2]
输出: true

解释: 能拼成一个边长为2的正方形,每边两根火柴。

示例 2:

输入: [3,3,3,3,4]
输出: false

解释: 不能用所有火柴拼成一个正方形。

注意:

  1. 给定的火柴长度和在 0 到 10^9之间。
  2. 火柴数组的长度不超过15。
class Solution {
public:
    vector<bool> st;
    bool makesquare(vector<int>& nums) {
        int sum=0;
        for(auto u:nums)
            sum+=u;
        if(!sum || sum%4 ) return false;
        sort(nums.begin(),nums.end());
        reverse(nums.begin(),nums.end());

        st=vector<bool>(nums.size());
        return dfs(nums,0,0,sum/4);
    }

    bool dfs(vector<int>& nums,int u,int cur,int length)
    {
        if(cur==length) u++,cur=0;
        if(u==4) return true;
        for(int i=0;i<nums.size();i++)
        {
            if(!st[i] && cur+nums[i]<=length)
            {
                st[i]=true;
                if(dfs(nums,u,cur+nums[i],length)) return true;
                st[i]=false;
                if(!cur) return false;
                if(cur+nums[i]==length) return false;
                while(i+1<nums.size() && nums[i+1]==nums[i]) i++;
            }    
        }
        return false;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值