Leedcode算法专题训练(分治法)
归并排序就是一个用分治法的经典例子,这里我用它来举例描述一下上面的步骤:
1、归并排序首先把原问题拆分成2个规模更小的子问题。
2、递归地求解子问题,当子问题规模足够小时,可以一下子解决它。在这个例子中就是,当数组中的元素只有1个时,自然就有序了。
3、最后,把子问题的解(已排好序的子数组)合并成原问题的解。

当待排序的序列长度为1时,递归“开始回升”,在这种情况下不要做任何工作,因为长度为1的每个序列都已排好序。归并排序算法的关键操作是“合并”步骤中两个已排序序列的合并。我们通过调用一个辅助过程Merge(A,p,q,r)来完成合并,其中A是一个数组,p、q和r是数组下标,满足p<=q<r。该过程假设子数组A[p,q]和A[q+1,r]都已排好序。它合并这两个子数组形成单一的已排好序的子数组并代替当前的子数组A[p,r]。
过程Merge按以下方式工作。回到我们玩扑克牌的例子,假设桌上有两堆牌面朝上的牌,每堆都已排序,最小的牌在顶上。我们希望把这两堆牌合并成单一的排好序的输出堆,牌面朝下地放在桌上。我们的基本步骤包括在牌面朝上的两堆牌的顶上两张牌中选取较小的一张,将该牌从其堆中移开(该堆的顶上将显露一张新牌)并牌面朝下地将该牌放置到输出堆。
下面是Merge的伪代码:
Merge(A,p,q,r):
tmp[1,..,r-p+1]
i = p
j = q+1
while i <= q && j <= r
if A[i] <= A[j]
tmp[k++] = A[i++];
else
tmp[k++] = A[j++];
while i <= q
tmp[k++] = A[i++];
while j <= r
tmp[k++] = A[j++];
for k2 = 0 to tmp.length
A[k2+p] = tmp[k2];
Java代码实现
public class Merge_sort_test {
public static void Merge(int[] A,int p,int q,int r){
int[] tmp = new int[r-p+1];//声明一个临时数组,长度为要归并数组的长度
int i = p; //记住左边数组第一个元素的下标
int j = q+1; //记住右边数组第一个元素的下标
int k = 0;
while(i <= q && j <= r){
//左边数组元素和右边数组元素比较,把小的元素赋给临时数组
if(A[i] <= A[j]){
tmp[k++] = A[i++];
}
else{
tmp[k++] = A[j++];
}
}
//把左边剩余的数组元素赋给临时数组
while(i <= q){
tmp[k++] = A[i++];
}
//把右边剩余的数组元素赋给临时数组
while(j <= r){
tmp[k++] = A[j++];
}
//用临时数组元素覆盖原数组元素
for(int k2 = 0;k2 < tmp.length;k2++){
A[k2+p] = tmp[k2];
}
}
public static void/*int[]*/ Merge_sort(int[] A,int p,int r){
int q = (p+r)/2;
if(p < r){
//递归调用
Merge_sort(A,p,q);
Merge_sort(A,q + 1,r);
//归并排序数据元素
Merge(A,p,q,r);
}
//return A;
}
public static void main(String[] args) {
//
int[] A = {5,2,4,7,1,3,2,6};
System.out.println("原始数据: ");
for(int i = 0;i < A.length;i++){
System.out.print(A[i] + " ");
}
System.out.println();
Merge_sort(A,0,A.length -1);
System.out.println("输出结果: ");
for(int i = 0;i < A.length;i++){
System.out.print(A[i] + " ");
}
}
}
1. 给表达式加括号
241. Different Ways to Add Parentheses (Medium)
Input: "2-1-1".
((2-1)-1) = 0
(2-(1-1)) = 2
Output : [0, 2]
这个解法真的很牛逼,注意分而治之的核心思想,先是把问题进行分解成一个小问题就是存储单个数字,然后再根据运算符进行计算

class Solution {
public List<Integer> diffWaysToCompute(String input) {
List<Integer> ways=new ArrayList<>();
for(int i=0;i<input.length();i++){
char c=input.charAt(i);
if(c=='+' || c == '-'|| c=='*'){
List<Integer> left = diffWaysToCompute(input.substring(0,i));
List<Integer> right = diffWaysToCompute(input.substring(i+1));
for(int l:left){
for(int r:right){
switch(c){
case '+':
ways.add(l+r);
break;
case '-':
ways.add(l-r);
break;
case '*':
ways.add(l*r);
break;
}
}
}
}
}
if(ways.size() == 0){
ways.add(Integer.valueOf(input));
}
return ways;
}
}
2. 不同的二叉搜索树
95. Unique Binary Search Trees II (Medium)
给定一个数字 n,要求生成所有值为 1...n 的二叉搜索树。
Input: 3
Output:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST's shown below:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
class Solution {
public List<TreeNode> generateTrees(int n) {
if(n==0)return new LinkedList<TreeNode>();
return generateTrees(1,n);
}
public List<TreeNode> generateTrees(int start ,int end){
List<TreeNode> allTrees = new LinkedList<TreeNode>();
if(start > end){
allTrees.add(null);
return allTrees;
}
for(int i=start;i<=end;i++){
List<TreeNode> leftTrees=generateTrees(start,i-1);
List<TreeNode> rightTrees=generateTrees(i+1,end);
for(TreeNode left:leftTrees){
for(TreeNode right : rightTrees) {
TreeNode currTree = new TreeNode(i);
currTree.left=left;
currTree.right=right;
allTrees.add(currTree);
}
}
}
return allTrees;
}
}
Leedcode算法专题训练(分治法)的更多相关文章
- Leedcode算法专题训练(排序)
排序 快速排序 用于求解 Kth Element 问题,也就是第 K 个元素的问题. 可以使用快速排序的 partition() 进行实现.需要先打乱数组,否则最坏情况下时间复杂度为 O(N2). 堆 ...
- Leedcode算法专题训练(搜索)
BFS 广度优先搜索一层一层地进行遍历,每层遍历都是以上一层遍历的结果作为起点,遍历一个距离能访问到的所有节点.需要注意的是,遍历过的节点不能再次被遍历. 第一层: 0 -> {6,2,1,5} ...
- Leedcode算法专题训练(二分查找)
二分查找实现 非常详细的解释,简单但是细节很重要 https://www.cnblogs.com/kyoner/p/11080078.html 正常实现 Input : [1,2,3,4,5] key ...
- Leedcode算法专题训练(贪心)
1. 分配饼干 455. 分发饼干 题目描述:每个孩子都有一个满足度 grid,每个饼干都有一个大小 size,只有饼干的大小大于等于一个孩子的满足度,该孩子才会获得满足.求解最多可以获得满足的孩子数 ...
- Leedcode算法专题训练(双指针)
算法思想 双指针 167. 两数之和 II - 输入有序数组 双指针的典型用法 如果两个指针指向元素的和 sum == target,那么得到要求的结果: 如果 sum > target,移动较 ...
- Leedcode算法专题训练(位运算)
https://www.cnblogs.com/findbetterme/p/10787118.html 看这个就完事了 1. 统计两个数的二进制表示有多少位不同 461. Hamming Dista ...
- Leedcode算法专题训练(数组与矩阵)
1. 把数组中的 0 移到末尾 283. Move Zeroes (Easy) Leetcode / 力扣 class Solution { public void moveZeroes(int[] ...
- Leedcode算法专题训练(数学)
204. 计数质数 难度简单523 统计所有小于非负整数 n 的质数的数量. class Solution { public int countPrimes(int n) { boolean[] is ...
- Leedcode算法专题训练(字符串)
4. 两个字符串包含的字符是否完全相同 242. Valid Anagram (Easy) Leetcode / 力扣 可以用 HashMap 来映射字符与出现次数,然后比较两个字符串出现的字符数量是 ...
随机推荐
- 在vscode中用Git管理项目
1.新建仓库-->填写仓库名称-->一定要将对钩去掉-->公开-->创建 Git全局设置: git config --global --add user.name " ...
- SpringCloud Sleuth
1.定义 Sleuth(分布式请求链路跟踪):提供了一套完整的服务跟踪解决方案,也兼容zipkin. 参考网址:https://github.com/spring-cloud/spring-cloud ...
- Ability之间或者进程间数据传递之对象(Sequenceable序列化)
鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 这两天51cto上的一个粉丝朋友问了我一个问题,Ability之间使用Sequenceable序列化传 ...
- 翻译:《实用的Python编程》03_00_Overview
目录 | 上一节 (2 处理数据) | 下一节 (4 类和对象) 3. 程序组织 到目前为止,我们已经学习了一些 Python 基础知识并编写了一些简短的脚本.但是,当开始编写更大的程序时,我们会想要 ...
- CentOS 7关闭firewalld启用iptables 开放端口
在CentOS7中,有很多CentOS 6中的常用服务发生了变化. 其中iptables是其中比较大的一个.防火墙iptables被firewalld取代. 本文将介绍,如果采用systemctl关闭 ...
- three.js cannon.js物理引擎之齿轮动画
郭先生今天继续说一说cannon.js物理引擎,并用之前已经学习过的知识实现一个小动画,知识点包括ConvexPolyhedron多边形.Shape几何体.Body刚体.HingeConstraint ...
- KL散度相关理解以及视频推荐
以下内容基于对[中字]信息熵,交叉熵,KL散度介绍||机器学习的信息论基础这个视频的理解,请务必先看几遍这个视频. 假设一个事件可能有多种结果,每一种结果都有其发生的概率,概率总和为1,也即一个数据分 ...
- CentOS7.8搭建STF
安装命令插件(rz.sz): yum install -y lrzsz wget unzip zip编辑配置文件导致命令无法使用时:export PATH=/usr/local/sbin:/usr/l ...
- 关于Python编写时候的一些数据格式调用问题
utf-8 可变长度字符串,互联网通用,目的是减少内存占用Unicode 万国码, 对于英文多占用一个字节ASCII码 美国编码1个字节Gb2313 中国编码 编码 encode解码 decodepy ...
- 目标检测入门论文YOLOV1精读以及pytorch源码复现(yolov1)
结果展示 其中绿线是我绘制的图像划分网格. 这里的loss是我训练的 0.77 ,由于损失函数是我自己写的,所以可能跟大家的不太一样,这个不重要,重要的是学习思路. 重点提示 yolov1是一个目标检 ...