归并排序就是一个用分治法的经典例子,这里我用它来举例描述一下上面的步骤:

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)

Leetcode / 力扣

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)

Leetcode / 力扣

给定一个数字 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算法专题训练(分治法)的更多相关文章

  1. Leedcode算法专题训练(排序)

    排序 快速排序 用于求解 Kth Element 问题,也就是第 K 个元素的问题. 可以使用快速排序的 partition() 进行实现.需要先打乱数组,否则最坏情况下时间复杂度为 O(N2). 堆 ...

  2. Leedcode算法专题训练(搜索)

    BFS 广度优先搜索一层一层地进行遍历,每层遍历都是以上一层遍历的结果作为起点,遍历一个距离能访问到的所有节点.需要注意的是,遍历过的节点不能再次被遍历. 第一层: 0 -> {6,2,1,5} ...

  3. Leedcode算法专题训练(二分查找)

    二分查找实现 非常详细的解释,简单但是细节很重要 https://www.cnblogs.com/kyoner/p/11080078.html 正常实现 Input : [1,2,3,4,5] key ...

  4. Leedcode算法专题训练(贪心)

    1. 分配饼干 455. 分发饼干 题目描述:每个孩子都有一个满足度 grid,每个饼干都有一个大小 size,只有饼干的大小大于等于一个孩子的满足度,该孩子才会获得满足.求解最多可以获得满足的孩子数 ...

  5. Leedcode算法专题训练(双指针)

    算法思想 双指针 167. 两数之和 II - 输入有序数组 双指针的典型用法 如果两个指针指向元素的和 sum == target,那么得到要求的结果: 如果 sum > target,移动较 ...

  6. Leedcode算法专题训练(位运算)

    https://www.cnblogs.com/findbetterme/p/10787118.html 看这个就完事了 1. 统计两个数的二进制表示有多少位不同 461. Hamming Dista ...

  7. Leedcode算法专题训练(数组与矩阵)

    1. 把数组中的 0 移到末尾 283. Move Zeroes (Easy) Leetcode / 力扣 class Solution { public void moveZeroes(int[] ...

  8. Leedcode算法专题训练(数学)

    204. 计数质数 难度简单523 统计所有小于非负整数 n 的质数的数量. class Solution { public int countPrimes(int n) { boolean[] is ...

  9. Leedcode算法专题训练(字符串)

    4. 两个字符串包含的字符是否完全相同 242. Valid Anagram (Easy) Leetcode / 力扣 可以用 HashMap 来映射字符与出现次数,然后比较两个字符串出现的字符数量是 ...

随机推荐

  1. 生成类库项目时同时生成的pdb文件是什么东东?

    英文全称:Program Database File Debug里的PDB是full,保存着调试和项目状态信息.有断言.堆栈检查等代码.可以对程序的调试配置进行增量链接.Release 里的PDB是p ...

  2. iframe重定向问题

    sandbox="allow-forms allow-scripts allow-same-origin allow-popups"

  3. 微信小程序:日期组件picker的使用

    1.页面代码 <view class="right"> <picker mode="date" value="{{material. ...

  4. 后端程序员之路 32、Index搜索引擎实现分析1-类的设计

    # 1.forward_index 正排索引(正向索引)- filter_t- filter_judge # 2.inverted_index 倒排索引(反向索引)- inverted_pre_sco ...

  5. 【DB宝41】监控利器PMM的使用--监控MySQL、PG、MongoDB、ProxySQL等

    目录 一.PMM简介 二.安装使用 三.监控MySQL数据库 MySQL慢查询分析 四.监控PG数据库 五.监控MongoDB数据库 六.监控ProxySQL中间件 一.PMM简介 之前发布过一篇Pr ...

  6. 基于CefSharp开发浏览器(八)浏览器收藏夹栏

    一.前言 上一篇文章 基于CefSharp开发(七)浏览器收藏夹菜单 简单实现了部分收藏夹功能 如(添加文件夹.添加收藏.删除.右键菜单部分功能) 后续代码中对MTreeViewItem进行了扩展,增 ...

  7. mysql内一些可以布尔盲注的查询语句

              一.left() 首先需要 use security;  这个数据库,然后进入之后再使用查询语句: 此时再使用: select left(database(),1)='s';    ...

  8. 解决 Ant Design Modal 中的 Select 选项框不能显示的问题

    antd 的 select 在 modal 里不能显示候选框 代码示例 <a-modal> <a-select> <!-- options --> </a-s ...

  9. SpringCloud里面切换数据源无效的问题

    问题描述: 调用链:controller1的接口A->service1的方法A->service2的方法B 方法A开启了事务,且指定了数据库A的数据源 方法B也开启了事务,使用了默认的事务 ...

  10. WPF 基础 - Trigger

    1. Trigger 1.1 由属性值触发的 Trigger 最基本的触发器,Property 是关注的属性名称,value 是触发条件,一旦触发条件满足,就会应用 Trigger 的 Setters ...