回溯算法

括号生成

给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]

vector<string> generate(int n){
  vector<string> result;
  helper(0, 0, "", result, n);
}

void helper(int left, int right, string out, vector<string>& result){
  if(left < 0 || right < 0 || left > right) return;
  if(left == 0 && right == 0){    //保持左右一致,且左边在前
      result.push_back(out);
      return;
  }
  helper(left-1, right, out+"(", result);
  helper(left, right-1, out+")", result);
}

全排列1-2

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

//没有重复时,用set即可
 vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        int n=nums.size();
        helper(nums, 0, n-1, res);
        return res;
    }
    
    void helper(vector<int>& a, int left,int right, vector<vector<int>> &res){
        if (left==right) {res.push_back(a);return;}
        for (int i=left; i<=right; ++i){
            swap(a[i], a[left]);
            helper(a,left+1,right,res);
            swap(a[i], a[left]);
        }
    }

子集1-2

输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

//不要重复,用set代替vector
    vector<vector<int> > subsets(vector<int>& nums) {
        int n=nums.size();
        vector<vector<int> > result;
        vector<int> res;
        helper(nums,res,result,0);
        return result;
    }  
    void helper(vector<int>& nums, vector<int>& res, vector<vector<int> >& result, int i){
        result.push_back(res);
        for(;i<nums.size();++i){    
            res.push_back(nums[i]);  
            helper(nums, res, result, i+1);
            res.pop_back();
        }
    } 

[组合总和1-2]

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]

//这一题也可以用指针来计算
vector<vector<int>> combi(vector<int>& nums, int target){
  vector<vector<int>> result;
  vector<int> res;
  sort(nums.begin(), nums.end());
  helper( nums, 0, target, res, result);
  return result;
}
void helper(vector<int>& nums, int start, int target, vector<int>& res, vector<vector<int>>& result){
  if(target < 0) return;
  if(target == 0) {
      result.push_back(res);
      return;
  }
  for(int i=start; i<nums.size(); ++i){
     //if(nums[i] == nums[i-1] && i>start) continue;    //不要重复的
    res.push_back(nums[i]);
    helper(nums, i, target-nums[i], res, result);
    res.pop_back();
  }
}

分割回文串

输入: "aab"
输出:
[
["aa","b"],
["a","a","b"]
]

vector<vector<string>> partition(string s){
  vector<vector<string>> result;
  vector<string> res;
  helper(res, result, s, 0);
  return result;
}
void helper(vector<string>& res, vector<vector<string>>& result, string s, int start){
  if(start>=s.size()) {
    result.push_back(res);  
    return;
  }
  for(int i=start;i<s.size();i++){
    int l=start;
    int r=i;
    while(s[l]==s[r] && l<=r){ l--;r++;}
    if(l>=r){
        res.push_back(s.substr(start, i-start+1));
        helper(s, i+1, res, result);
        res.pop_back();
    }
  }

}

复原ip地址

输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]

    vector<string> restoreIpAddresses(string s) {
        vector<string> res;
        helper(s, 0, "", res);
        return res;
    }
    
    void helper(string s, int n, string out, vector<string>& res){
        if(n==4){
            if (s.empty()) res.push_back(out);
            return;
        }
            for(int k=1;k<4;++k){  //每一个最多3位数
                if(s.size() < k) break;
                int val = atoi(s.substr(0,k).c_str());
                if (val > 255 || k!=to_string(val).size()) continue;
                helper(s.substr(k), n+1, out+s.substr(0,k)+(n==3?"":"."), res);
            
        }
    }

单词搜索

给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]
给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.

 bool exist(vector<vector<char>>& board, string word) {
        if (board.empty() || board[0].empty()) return false;
        int m = board.size(), n = board[0].size();
        vector<vector<bool>> visited(m, vector<bool>(n, false));
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (search(board, word, 0, i, j, visited)) return true;
            }
        }
        return false;
    }
    bool search(vector<vector<char>>& board, string word, int idx, int i, int j, vector<vector<bool>>& visited) {
        if (idx == word.size()) return true;
        int m = board.size(), n = board[0].size();
        if (i < 0 || j < 0 || i >= m || j >= n || visited[i][j] || board[i][j] != word[idx]) return false;
        visited[i][j] = true;
        bool res = search(board, word, idx + 1, i - 1, j, visited) 
                 || search(board, word, idx + 1, i + 1, j, visited)
                 || search(board, word, idx + 1, i, j - 1, visited)
                 || search(board, word, idx + 1, i, j + 1, visited);
        visited[i][j] = false;
        return res;
    }

电话号码的组合

void helper (string digits, vector<string>& vec, string res, vector<string>& result){
    if (digits.length() == 0){
        result.push_back(res);
    }else{
        string digit = digits.substr(0,1);
        int num = atoi(digit.c_str());
        //int num = digits[0] - '0';
        string letters = vec[num-2];
        for(int i = 0; i < letters.length(); i++){
            string letter = letters.substr(i,i+1);
            helper(digits.substr(1), vec, res+letter, result);
        }  
    }
}     
vector<string> letterCombinations(string digits, vector<string>& vec) {
    vector<string> result;
    if (digits.length() != 0)
     helper(digits, vec, "", result);
    return result;  
}
     
int main(){
    string s[]={"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    vector<string> vec(s,s+sizeof(s)/sizeof(string));
    string digits="23";
    vector<string> result = letterCombinations(digits, vec);
}

通配符匹配

正则表达式匹配

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容