# 诗经·秦风·无衣
岂曰无衣,与子同袍。王于兴师,修我戈矛。与子同仇。
岂曰无衣,与子同泽。王于兴师,修我矛戟。与子谐作。
岂曰无衣,与子同裳。王于兴师,修我甲兵。与子谐行。
#把正确的时间拿来看看书而不是低级趣味。。。

0.摘要

\qquad 递归的原则:当前步骤处理当前的问题,递归处理后续问题;
\qquad 回溯:探索到某一步时,发现原先选择达不到目标,则后退一步重新选择,走不通就退回再走
\qquad 分治:将原问题分解为若干个**“不相关”**的子问题。

1.回溯法

1.1 基于暴力的二分树


#include<vector>
vector<vector<int>> subsets(vector<int>& nums)
{vector<vector<int>> result;vector<int> item;result.push_back(item); //先将空集入vgenerate(0,nums,item,result);return result;
}
void generate(int i, vector<int>& item, vector<vector<int>>& reuslt)
{if(i==nums.size()) return;item.push_back(nums[i]);result.push_back(item); //选择第i个元素,并写入结果generate(i+1,nums,item,result); //递归后续元素item.pop_back(); //不选择第i个元素generate(i+1,nums,item,result); //递归后续元素
}

利用二进制数模拟三个元素【A,B,C】左右位置表示进制

vector<vector<int>> subsets(vector<int>&nums)
{vector<vector<int>> result;int iterations = 1<<nums.size(); //匹配总可能数for(int i=0; i<iterations; ++i){vector<int> item;//将每一个位置的j赋予底幂,匹配是否在item中for(int j=0; j<nums.size(); ++j){if(i&&(1<<j)){item.push_back(nums[j]);}result.push_back(item);}}return result;
}

1.2递归树剪枝,降低复杂度


A:对于明显不满足要求的结果,提前终止递归

#include<vector>
#include<set>
#include<algorithm>vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {sort(candiates.begin(),candidates.end());vector<int> item;vector<vector<int>> result;set<vector<int>> res_set;generate(0,candidates,item,result,res_set,0,target);   return result;}void generate(int i, vector<int>&candidates,vector<int>&item,vector<vector<int>>& result,set<vector<int>>&res_set,int sum, int target){if(sum>target || i==num.size()) return;item.push_back(candidate[i]);sum += candidate[i];if(sum==target && res_set.find(item)==res_set.end()){res_set.insert(item);result.push_back(item);}generate(i+1,candidates,item,result,res_set,sum,target); sum -= candidates[i];item.pop_back();generate(i+1,candidates,item,result,res_set,sum,target); }


A:在递归生成时,判断左右括号匹配进行剪枝

vector<string> generateParenthesis(int n)
{vector<string> result;generate("",n,n,result);return result;
}
void generate(string item,,int left,int right,vector<string>& result)
{if(left==0&&right==0){result.push_back(item);return;}if(left>0)generate(item+'(',left-1,right,result);if(right>left)genertae(item+')',left,right-1,result);
}

2.N皇后问题


#include<iostream>
using namespace std;
#include<vector>
#include<string>void change_flag(int x, int y, vector<vector<int> >&flag)
{int d_x[] = {-1,-1,-1,0,0,1,1,1};int d_y[] = {-1,0,1,-1,1,-1,0,1};flag[x][y] = 1;for(int i=1;i<flag.size();++i){for(int j=0; j<8; ++j){int newx = x + i*d_x[j];int newy = y + i*d_y[j];if(newx>=0 && newx<flag.size() && newy>=0 && newy<flag.size()){flag[newx][newy] = 1;}}}
}void generate(int k, int n, vector<vector<int> >&flag, vector<string>&item, vector<vector<string> >&result)
{if(k==n) {result.push_back(item);return;}for(int i=0; i<n; ++i){if(flag[k][i]==0){vector<vector<int> > tep = flag;item[k][i] = 'Q';change_flag(k,i,flag);cout<<flag[1][1];generate(k+1,n,flag,item,result);flag = tep;item[k][i] = '.';}}}vector<vector<string> > solveNQueens(int n)
{vector<string> item;vector<vector<string> > result;vector<vector<int> > flag;for(int i=0; i<n;++i){flag.push_back(vector<int>());item.push_back("");for(int j=0; j<n; ++j){flag[i].push_back(0);item[i].push_back('.');}}generate(0,n,flag,item,result);return result;
}

3.分治算法

\qquad 将一个规模为N的问题分解为K个规模较小的子问题,这些子问题之间相互独立且与原问题性质相同,求出子问题之后再合并,就可以得到原问题的解。

3.1归并排序

#include<vector>
void merge_sort(vector<int>&nums)
{if(nums.size()<2) return;int mid = nums.size()>>1;vector<vector<int>> sub_left_nums;vector<vector<int>> sub_right_nums;for(int i=0; i<mid; ++i){sub_left_nums.push_back(nums[i]);}for(int i=mid; i<nums.size(); ++i){sub_right_nums.push_back(nums[i]);}merge_sort(sub_left_nums);merge_sort(sub_right_nums);nums.clear();merge_two_sub(sub_left_nums, sub_right_nums, nums);
}void merge_two_sub(vector<int>&sub_left_nums,vector<int>&sub_right_nums,vector<int>&nums)
{int i=0; int j=0;while(i<sub_left_nums.size() && j<sub_right_nums.size()){if(sub_left_nums[i]<sub_right_nums[j]){nums.push_back(sub_left_nums[i]);}else{nums.push_back(sub_right_nums[j]);}}for(;i<sub_left_nums[i];++i){nums.push_back(sub_left_nums[i]);}for(;j<sub_right_nums[j];++j){nums.push_back(sub_right_nums[j]);}
}

3.2改造归并排序,求逆序数


class Solution {public:vector<int> countSmaller(vector<int>& nums) {vector<pair<int, int>> vec;vector<int> count;for(int i=0; i<nums.size(); ++i){vec.push_back(make_pair(nums[i],i));count.push_back(0);}merge_sort(vec,count);return count;}
private:void merge_sort_two(vector<pair<int, int>>& sub_vec1, vector<pair<int, int>>& sub_vec2, vector<pair<int,int>>&vec, vector<int>& count){int i=0; int j=0;while(i<sub_vec1.size() && j<sub_vec2.size()){if(sub_vec1[i].first <= sub_vec2[j].first){count[sub_vec1[i].second] += j;vec.push_back(sub_vec1[i]);++i;}else{vec.push_back(sub_vec2[j]);++j;}}for(; i<sub_vec1.size();++i){count[sub_vec1[i].second] += j;vec.push_back(sub_vec1[i]);}for(; j<sub_vec2.size();++j){vec.push_back(sub_vec2[j]);}}void merge_sort(vector<pair<int,int>>& vec, vector<int>&count){if(vec.size()<2) return;int mid = vec.size()>>1;vector<pair<int,int>> sub_vec1;vector<pair<int,int>> sub_vec2;for(int i=0; i<mid; ++i){sub_vec1.push_back(vec[i]);}for(int i=mid; i<vec.size();++i){sub_vec2.push_back(vec[i]);}merge_sort(sub_vec1,count);merge_sort(sub_vec2,count);vec.clear();merge_sort_two(sub_vec1,sub_vec2,vec,count);}
};

对于分治和回溯,目前来看都是基于递归树【二叉树或者多叉树】的构建思路,在复杂度较高的情况下,考虑生成剪枝算法抑制树的形状。

LeetCode刷题---递归回溯分治【2020第一版】相关推荐

  1. LeetCode 刷题之旅(2020.05.22)——105. 从前序与中序遍历序列构造二叉树(中)

    LeetCode 刷题之旅(2020.05.22)--105. 从前序与中序遍历序列构造二叉树(中) 题目: 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如, ...

  2. C#LeetCode刷题-递归

    递归篇 # 题名 刷题 通过率 难度 687 最长同值路径 30.8% 简单 698 划分为k个相等的子集 30.7% 中等 726 原子的数量 37.2% 困难 761 特殊的二进制序列 50.5% ...

  3. LeetCode刷题Python实录

    使用Python的LeetCode刷题 前言 题目 1408. 数组中的字符串匹配 508. 出现次数最多的子树元素和 1089. 复写零 剑指 Offer 14- I. 剪绳子 1175. 质数排列 ...

  4. C#LeetCode刷题-分治算法

    分治算法篇 # 题名 刷题 通过率 难度 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组的中位数(Median of Two Sorted Arrays)-该题未达最优解 30 ...

  5. Leetcode刷题

    刷题 leetcode 1.两数之和 #哈希表 class Solution:def twoSum(self, nums: List[int], target: int) -> List[int ...

  6. leetcode刷题优质题解(C++,Python,Go语言)

    最近开始为秋招准备,深感自己的编程能力基础弱,遂希望通过刷leetcode来提升数据结构和算法分析能力.过程中发现了几个优质题解,分享给大家,尤其是Carl哥的代码随想录包含C++.Java.Pyth ...

  7. LeetCode刷题框架总结

    LeetCode刷题框架总结 01 | 数组和链表遍历框架 1.数组遍历框架,典型的线性迭代结构 void traverse(int[] arr) {for (int i = 0; i < ar ...

  8. 个人LeetCode刷题记录(带题目链接及解答)持续更新

    Leetcode 刷题 注:~[完成]代表还有一些方法没看,最后再看 一.一些需要重刷的典型题: 1.快速排序,归并排序,堆排序(递归的思想) 2.链表中的回文链表,其中的快慢指针,多看,多练 3.链 ...

  9. LeetCode刷题2

    0612 LeetCode刷题2 力扣刷题1 力扣刷题2 力扣83题:删除排序链表中的重复元素 力扣82题:删除排序链表中的重复元素II 力扣第8题:字符串转换整数 (atoi) 力扣22题:括号生成 ...

最新文章

  1. eachart图表100px大小原因,及处理办法
  2. [转]web.xml 中的listener、 filter、servlet 加载顺序及其详解
  3. hbase shell-dml(数据管理指令)
  4. 深度搜索问题c语言,C语言实现的图的深度搜索与广度搜索程序.doc
  5. JAVA面对对象(一)——封装
  6. oracle数据库报错1033,Oracle联机日志出现错误ORA-16038 ORA-19809 ORA-00312 解决
  7. 为什么需要 AtomicInteger 原子操作类?
  8. js动态生产table、Div、select
  9. numpy 维度与轴的问题
  10. 大型网站技术架构之技术一览
  11. 2017-2018 ACM-ICPC, NEERC A题Automatic Door 挺棘手的模拟
  12. 为什么动物不需要吃盐
  13. c语言中的单词的意思及作用,c语言入门必背单词 具体含义是什么
  14. MMORPG大型游戏设计与开发(概述)updated
  15. 超声波传感器测距实验430
  16. CC2430 定时器溢出中断 详解
  17. ElasticSearch高级功能的使用(模版查询、地理位置查询等)
  18. android中如何让动画停止,让Android AnimatorSet停止制作动画
  19. Apple Watch使用指南:所有Apple Watch图标和符号含义
  20. 前端图片上传那些事儿

热门文章

  1. 快手于冰:咱客户端工程师,还可以往哪个方向纵深?
  2. java awt robot
  3. 微信小程序生态13-微信公众号自定义菜单、个性化菜单配置
  4. jplayer指定html5,jplayer列表播放错误自动进入下一首方法
  5. 十大高蛋白质食品 补充蛋白质的最佳选择
  6. 基于LVM进行磁盘分区
  7. 求某一范围的纯粹素数(C语言函数例题)
  8. 微信公众号菜单栏规划怎么设置?
  9. elasticsearch中分词器edge_ngram和ngram的区别
  10. 运行MySQL报错:找不到命令mysql、ERROR 2003 (HY000)、ERROR 1045 (28000)