LeetCode刷题---递归回溯分治【2020第一版】
# 诗经·秦风·无衣
岂曰无衣,与子同袍。王于兴师,修我戈矛。与子同仇。
岂曰无衣,与子同泽。王于兴师,修我矛戟。与子谐作。
岂曰无衣,与子同裳。王于兴师,修我甲兵。与子谐行。
#把正确的时间拿来看看书而不是低级趣味。。。
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第一版】相关推荐
- LeetCode 刷题之旅(2020.05.22)——105. 从前序与中序遍历序列构造二叉树(中)
LeetCode 刷题之旅(2020.05.22)--105. 从前序与中序遍历序列构造二叉树(中) 题目: 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如, ...
- C#LeetCode刷题-递归
递归篇 # 题名 刷题 通过率 难度 687 最长同值路径 30.8% 简单 698 划分为k个相等的子集 30.7% 中等 726 原子的数量 37.2% 困难 761 特殊的二进制序列 50.5% ...
- LeetCode刷题Python实录
使用Python的LeetCode刷题 前言 题目 1408. 数组中的字符串匹配 508. 出现次数最多的子树元素和 1089. 复写零 剑指 Offer 14- I. 剪绳子 1175. 质数排列 ...
- C#LeetCode刷题-分治算法
分治算法篇 # 题名 刷题 通过率 难度 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组的中位数(Median of Two Sorted Arrays)-该题未达最优解 30 ...
- Leetcode刷题
刷题 leetcode 1.两数之和 #哈希表 class Solution:def twoSum(self, nums: List[int], target: int) -> List[int ...
- leetcode刷题优质题解(C++,Python,Go语言)
最近开始为秋招准备,深感自己的编程能力基础弱,遂希望通过刷leetcode来提升数据结构和算法分析能力.过程中发现了几个优质题解,分享给大家,尤其是Carl哥的代码随想录包含C++.Java.Pyth ...
- LeetCode刷题框架总结
LeetCode刷题框架总结 01 | 数组和链表遍历框架 1.数组遍历框架,典型的线性迭代结构 void traverse(int[] arr) {for (int i = 0; i < ar ...
- 个人LeetCode刷题记录(带题目链接及解答)持续更新
Leetcode 刷题 注:~[完成]代表还有一些方法没看,最后再看 一.一些需要重刷的典型题: 1.快速排序,归并排序,堆排序(递归的思想) 2.链表中的回文链表,其中的快慢指针,多看,多练 3.链 ...
- LeetCode刷题2
0612 LeetCode刷题2 力扣刷题1 力扣刷题2 力扣83题:删除排序链表中的重复元素 力扣82题:删除排序链表中的重复元素II 力扣第8题:字符串转换整数 (atoi) 力扣22题:括号生成 ...
最新文章
- eachart图表100px大小原因,及处理办法
- [转]web.xml 中的listener、 filter、servlet 加载顺序及其详解
- hbase shell-dml(数据管理指令)
- 深度搜索问题c语言,C语言实现的图的深度搜索与广度搜索程序.doc
- JAVA面对对象(一)——封装
- oracle数据库报错1033,Oracle联机日志出现错误ORA-16038 ORA-19809 ORA-00312 解决
- 为什么需要 AtomicInteger 原子操作类?
- js动态生产table、Div、select
- numpy 维度与轴的问题
- 大型网站技术架构之技术一览
- 2017-2018 ACM-ICPC, NEERC A题Automatic Door 挺棘手的模拟
- 为什么动物不需要吃盐
- c语言中的单词的意思及作用,c语言入门必背单词 具体含义是什么
- MMORPG大型游戏设计与开发(概述)updated
- 超声波传感器测距实验430
- CC2430 定时器溢出中断 详解
- ElasticSearch高级功能的使用(模版查询、地理位置查询等)
- android中如何让动画停止,让Android AnimatorSet停止制作动画
- Apple Watch使用指南:所有Apple Watch图标和符号含义
- 前端图片上传那些事儿
热门文章
- 快手于冰:咱客户端工程师,还可以往哪个方向纵深?
- java awt robot
- 微信小程序生态13-微信公众号自定义菜单、个性化菜单配置
- jplayer指定html5,jplayer列表播放错误自动进入下一首方法
- 十大高蛋白质食品 补充蛋白质的最佳选择
- 基于LVM进行磁盘分区
- 求某一范围的纯粹素数(C语言函数例题)
- 微信公众号菜单栏规划怎么设置?
- elasticsearch中分词器edge_ngram和ngram的区别
- 运行MySQL报错:找不到命令mysql、ERROR 2003 (HY000)、ERROR 1045 (28000)