-
序言:
- 刷LeetCode算法题时看人家解题方法是用回溯算法时,瞬间感觉到该题用该算法就很简单。细看了回溯算法后个人感觉回溯与递归有异曲同工之妙。
-
什么是递归呢???
- 递归是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象。递归通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
- 简单来说为了描述问题的某一状态,必须用到该状态的上一个状态;而如果要描述上一个状态,又必须用到上一个状态的上一个状态…… 这样用自己来定义自己的方法就是递归。
- 基本思想是从唯一的一条路往前走,能进则进,不能进就退回来,直至退回路的起点。
-
那什么是回溯呢???
- 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
- 简单来说就是回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。
- 基本思想是从一条路往前走,能进则进,不能进则回退,换条路重新出发,直到所有路走完或达到目标为止。
一、递归
(1)应用:合并两个有序链表
lass Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1==nullptr&&l2==nullptr) return nullptr;
if(l1==nullptr&&l2!=nullptr) return l2;
if(l1!=nullptr&&l2==nullptr) return l1;
if(l1->val > l2->val) {
l2->next=mergeTwoLists(l1,l2->next);
return l2;
}
else {
l1->next=mergeTwoLists(l1->next,l2);
return l1;
}
}
};
(2)应用:删除链表的倒数第 N 个结点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n)
{
//递归
if(head==nullptr) return nullptr;
head->next=removeNthFromEnd(head->next,n);
index++;
if(index==n) return head->next;
return head;
}
int index=0;
};
二、回溯
(1)应用:电话号码的字母组合
class Solution {
public:
vector<string> letterCombinations(string str) {
vector<string>strTel;
if(str.empty()) return strTel;
string strOfTel;
backTrack(strTel,phoneMap,str,0,strOfTel);
return strTel;
};
void backTrack(vector<string>&strTel,const unordered_map<char,string>phoneMap, string&str,int index, string&strOfTel){
if(index==str.length()) strTel.push_back(strOfTel);
else{
char c=str[index];
const string&letters=phoneMap.at(c);
for(const char&letter:letters){
strOfTel.push_back(letter);
backTrack(strTel,phoneMap,str,index+1,strOfTel);
strOfTel.pop_back();
}
}
}
private:
unordered_map<char, string> phoneMap{
{'2', "abc"},
{'3', "def"},
{'4', "ghi"},
{'5', "jkl"},
{'6', "mno"},
{'7', "pqrs"},
{'8', "tuv"},
{'9', "wxyz"}
};
};