leetcode回溯法

10.Regular Expression Matching

 

Implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true
class Solution {
public:
    bool isMatch(string s, string p) {
        if(s.length()==0){
            if (p.length() & 1) return false;
            else{
              for(int i=1;i<p.length();i+=2){
                if(p[i]!='*') return 0;
            }    
            }
            return 1;
        }
        if(p.length()==0) return 0;
        if(p.length()>1&&p[1]=='*'){
            if(s[0]==p[0]||p[0]=='.'){
                return isMatch(s.substr(1),p)||isMatch(s,p.substr(2));
            }
            else return isMatch(s,p.substr(2));
        }
         else if(s[0]==p[0]||p[0]=='.'){
            return isMatch(s.substr(1),p.substr(1));
        }
        else return 0;
    }
};

17Letter Combinations of a Phone Number

 

Given a digit string, return all possible letter combinations that the number could represent.

 

A mapping of digit to letters (just like on the telephone buttons) is given below.

Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

 

class Solution {//法一
public:
    const vector<string> keybord={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    vector<string> result;
    void backtrack(string remain){
        string th=keybord[remain[0]-'0'];
        if(result.empty()){
            for(auto i:th){
                string str="";
                str+=i;//若令str=""+i则不可以,因为只有将""创建为string时才可以对string类型使用+运算符
                result.push_back(str);
            }
        }
        else{
           vector<string> temp=result;
           result.clear();
           for (int i=0;i<th.length();i++){
             for(int j=0;j<temp.size();j++){
                string tt=temp[j]+th[i];
                result.push_back(tt);
             }
           } 
        }        
        if(remain.length()>1)
        backtrack(remain.substr(1));
        else return;
    }
    vector<string> letterCombinations(string digits) {
        backtrack(digits);
        return result;
    }
};
class Solution {//法二(深度优先搜索dfs)
public:
    const vector<string> keybord={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};    
    vector<string> letterCombinations(string digits) {
        if(digits=="") return{};
        vector<string> result;
        dfs(digits,0,"",result);
        return result;
    }
    void dfs(string &digits,int start,string path,vector<string> &result){
        if(start==digits.length()){
            result.push_back(path);
            return;
        }
        for(auto c:keybord[digits[start]-'0']){
            dfs(digits,start+1,path+c,result);
        }
    }
};


22Generate Parentheses

 

 

 

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]
class Solution {
public:
    vector<string> result;
    void dfs(int n,int leftnum,string cur,int mached){
        if(leftnum<0) return;
        if(leftnum+mached>n) return;
        if(mached==n&&leftnum==0) {
            result.push_back(cur);
            return;
        }    
        dfs(n,leftnum+1,cur+'(',mached);
        dfs(n,leftnum-1,cur+')',mached+1);    
    }
    vector<string> generateParenthesis(int n) {
        dfs(n,0,"",0);
        return result;
    }
};

37Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.

A sudoku puzzle...

 

...and its solution numbers marked in red.

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        sove(board);
    }
    bool sove(vector<vector<char>>& board){
        for(int i=0;i<board.size();i++){
            for(int j=0;j<board.size();j++){
                if(board[i][j]!='.') continue;
                if(board[i][j]=='.'){
                    for(int k=1;k<=9;k++){
                        board[i][j]='0'+k;
                        if(isValidSudoku(board)&&sove(board)){
                            return true;//这里若用void类型函数作为回溯函数则无法判断是否已找到
                        }
                        board[i][j]='.';
                    }
                }
                return false;//i,j位置上填任何数都不合法;
            }
        }
        return true;
    }
    bool isValidSudoku(vector<vector<char>>& board) //略

39Combination Sum

Given a set of candidate numbers (C(without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

The same repeated number may be chosen from C unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

 

For example, given candidate set [2, 3, 6, 7] and target 7
A solution set is: 

[
  [7],
  [2, 2, 3]
]
class Solution {
public:
    void dfs(vector<vector<int>>& result,vector<int>& candidates, int target,int start,vector<int>& cur)
    {
        if(target==0){
            result.push_back(cur);
            return;
        }
        if(target<0) return;
        for(int i=start;i<candidates.size();i++){
             cur.push_back(candidates[i]);
            dfs(result,candidates,target-candidates[i],i,cur);
            cur.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> result;
        vector<int> cur;
        dfs(result,candidates,target,0,cur);
        return result;
    }
};

40Combination Sum II

Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

Each number in C may only be used once in the combination.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

 

For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8
A solution set is: 

[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]
class Solution {
public:
    void dfs(vector<vector<int>>& result,vector<int>& candidates, int target,int start,vector<int>& cur)
    {
        if(target==0){
            result.push_back(cur);
            return;
        }
        if(target<0) return;
        for(int i=start;i<candidates.size();i++){
            if(i>start&&candidates[i]==candidates[i-1]) continue;//要使结果不重复只要使遍历的首元素不重复即可
             cur.push_back(candidates[i]);
            dfs(result,candidates,target-candidates[i],i+1,cur);
            cur.pop_back();
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<vector<int>> result;
        vector<int> cur;
        sort(candidates.begin(),candidates.end());
        dfs(result,candidates,target,0,cur);
        return result;
    }
};

131. Palindrome Partitioning

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

Example:

Input: "aab"
Output:
[
  ["aa","b"],
  ["a","a","b"]
]
class Solution {
    public List<List<String>> partition(String s) {
        List<List<String>> res = new ArrayList<>();
        if(s==null ||s.length()==0){
            return res;
        }
        List<String> partition = new ArrayList<String>();
        helper(s,0,partition,res);
        return res;
        
    }
    private void helper(String s,int start,List<String> partition,List<List<String>> res){//双指针遍历
        
        if(start==s.length()){//检查边界情况
            res.add(new ArrayList<String>(partition));
        }
        for (int i = start;i<s.length();i++){//展开所有情况
            if(ifPalindorme(s.substring(start,i+1))){
                partition.add(s.substring(start,i+1));
                helper(s,i+1,partition,res);
                partition.remove(partition.size()-1);
            }
        }
        
    }
    private boolean ifPalindorme(String s){
        char[] str = s.toCharArray();
        int i =0;
        int len = str.length;
        while(i<=len-i-1){
            if (str[i]!=str[len-i-1]){
                return false;
            }
            i++;
        }
        return true;
    }
}


总结一下,回溯法的一般步骤为

   1 判断当前是否为解(匹配,合法...)

   2检查边界情况

   3遍历当前点的所有可能并一一展开

 

第10题和第37题属于一类问题——零一问题,即判断是否匹配,或者只有唯一解时需要判断能否解出此解。此类问题的辅助函数一般为bool型。

其余题为另一类——找所有解问题。此类问题的返回值一般为一个容器类,辅助函数一般为void类型。



class Solution(object):
    def restoreIpAddresses(self, s):
        
    def findip(self,s,start,result,cur,num)
        if num == 4:
            result.append(cur) if cur not in result
            return
        if (len(s)-start)>(4-num)*3:
            return
        if int(s[start:start+3])<256 and start+3<len(s):
            findip(s,start+3,result,cur+s[start:start+3]+'.',num+1)
        elif int(s[start:len(s)])<256 and start+3>=len(s):
            findip(s,start+3,result,cur+s[start:len(s)],num+1)
        elif start+3>=len(s) and int(s[start:len(s)])>255: return
        else:
            findip(s,start+2,result,cur+s[start:start+2]+'.',num+1)
            findip(s,start+1,result,cur+s[start:start+1]+'.',num+1)
     

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值