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 来映射字符与出现次数,然后比较两个字符串出现的字符数量是 ...
随机推荐
- VOR/DME程序进近、复飞保护区的绘制
今天尝试画一个典型的VOR/DME进近程序保护区. 读图 某机场VOR/DME进近程序平面图部分如下图所示: 该程序剖面图部分如下图所示: 分析 该机场采用了偏置导航台布局(导航台在机场内), ...
- 遇见ZooKeeper:初识
0. 什么是ZooKeeper ZooKeeper 是一个开源的分布式,它的设计目标是将那些复杂且容易出错的分布式协同服务封装起来,抽象出一个高效可靠的原语集,并以一系列简单的接口提供个用户使用. Z ...
- centos7.5+nginx+php急速配置
centos7.5+nginx+php急速配置 centosnginxphp 更新系统以及添加源 yum update yum -y install epel-release 安装php以及配置 yu ...
- fastjson 反弹shell
目录 如下文章说得很不详细,只是用于记录我的步骤,初次利用的人,建议找别的博客文章学习. 准备一台公网服务器 cd test python -m SimpleHTTPServer 8888 javac ...
- PAT-1154(Vertex Coloring )+map使用+vector建图+set的使用
Vertex Coloring PAT-1154 #include<iostream> #include<cstring> #include<string> #in ...
- Pytorch1.7报错 Output 0 of UnbindBackward is a view and is being modified inplace
utils里内容改成 if scale_each is True: for idx, _ in enumerate([jj for jj in tensor]): t = tensor[idx] # ...
- 【老孟Flutter】Flutter 2的新功能
老孟导读:昨天期待已久的 Flutter 2.0 终于发布了, Flutter Web和Null安全性趋于稳定,Flutter桌面安全性逐渐转向Beta版! 原文链接:https://medium.c ...
- There only 10 people use the same phone as you(i春秋CTF题解)
(1)访问网址进行CTF测试,仅出现登陆与注册的页面 (2)进行注册尝试登陆并进行burp抓取数据包: (3)注册成功,进行登陆尝试查看信息是否具有提示,在登录的页面只有两个点击页面,一个为:Ch ...
- Java 树结构的基础部分(二)
1 顺序存储二叉树 1.1 顺序存储二叉树的概念 基本说明 从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组, 看下面的示意图. 要求: 1) 右 ...
- Pyqt5学习笔记(一)
Python已有的GUI框架: Tkinter(python内嵌的GUI环境,使用TCL实现,易学易用,方便简单创GUI自带无需安装,适用于Unix.Windows和Mac系统组,在Tk8.0的后续版 ...